简体   繁体   English

标准是否要求自动存储中的对象具有任何类型的正确对齐方式(例如,malloc确实如此)?

[英]Does the standard require that objects in automatic storage have the correct alignment for any type (e.g. as malloc does)?

I'm curious if allocating a buffer on the stack is required to have correct alignment for any type, similar to how malloc works, or if I would be forced to use something like std::aligned_storage . 我很好奇是否需要在堆栈上分配缓冲区以便为任何类型进行正确的对齐,类似于malloc工作方式,或者我是否会被迫使用类似std::aligned_storage东西。

Consider the following block of code: 考虑以下代码块:

typedef enum _KEY_VALUE_INFORMATION_CLASS {
    KeyValueBasicInformation            = 0,
    // Others
} KEY_VALUE_INFORMATION_CLASS;

typedef struct _KEY_VALUE_BASIC_INFORMATION {
    ULONG TitleIndex;
    ULONG Type;
    ULONG NameLength;
    WCHAR Name[1];
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;

std::vector<std::wstring> RegistryKey::EnumerateValueNames() const
{
    std::vector<std::wstring> result;
    ULONG index = 0;
    const ULONG valueNameStructSize = 16384 * sizeof(wchar_t) +
        sizeof(KEY_VALUE_BASIC_INFORMATION);

    // Stack buffer here
    unsigned char buff[valueNameStructSize];
    // Casted here
    KEY_VALUE_BASIC_INFORMATION const* basicValueInformation =
        reinterpret_cast<KEY_VALUE_BASIC_INFORMATION const*>(buff);
    for(;;)
    {
        ULONG resultLength;
        NTSTATUS errorCheck = PNtEnumerateValueKeyFunc(
            hKey_,
            index++,
            KeyValueBasicInformation,
            buff,
            valueNameStructSize,
            &resultLength);
        if (NT_SUCCESS(errorCheck))
        {
            result.emplace_back(std::wstring(basicValueInformation->Name,
                basicValueInformation->NameLength / sizeof(wchar_t)));
        }
        else if (errorCheck == STATUS_NO_MORE_ENTRIES)
        {
            break;
        }
        else
        {
            Win32Exception::ThrowFromNtError(errorCheck);
        }
    }
    return result;
}

Note how the value buff is a character buffer put on the stack, sized to hold a given maximum amount of data. 请注意值buff是如何放置在堆栈上的字符缓冲区,其大小可以容纳给定的最大数据量。 However, I'm concerned that the cast required to interpret the buffer as a string may cause an alignment fault if this code were to be ported to another (say ARM or IA64) platform. 但是,我担心将缓冲区解释为字符串所需的强制转换可能会导致对齐错误,如果此代码要移植到另一个(例如ARM或IA64)平台。

EDIT: If anyone's curious, I redid this in terms of std::aligned_storage and std::alignment_of : 编辑:如果有人好奇,我在std::aligned_storagestd::alignment_of方面std::aligned_storage

std::vector<std::wstring> RegistryKey::EnumerateValueNames() const
{
    std::vector<std::wstring> result;
    ULONG index = 0;
    const ULONG valueNameStructSize = 16384 * sizeof(wchar_t) +
        sizeof(KEY_VALUE_BASIC_INFORMATION);
    std::aligned_storage<valueNameStructSize,
        std::alignment_of<KEY_VALUE_BASIC_INFORMATION>::value>::type buff;
    auto basicValueInformation =
        reinterpret_cast<KEY_VALUE_BASIC_INFORMATION*>(&buff);
    for(;;)
    {
        ULONG resultLength;
        NTSTATUS errorCheck = PNtEnumerateValueKeyFunc(
            hKey_,
            index++,
            KeyValueBasicInformation,
            basicValueInformation,
            valueNameStructSize,
            &resultLength);
        if (NT_SUCCESS(errorCheck))
        {
            result.emplace_back(std::wstring(basicValueInformation->Name,
                basicValueInformation->NameLength / sizeof(wchar_t)));
        }
        else if (errorCheck == STATUS_NO_MORE_ENTRIES)
        {
            break;
        }
        else
        {
            Win32Exception::ThrowFromNtError(errorCheck);
        }
    }
    return std::move(result);
}

The standard makes no requirements on the alignment of automatic variables (or variables with static storage for that matter), other than the compiler must make sure that accessing them works. 该标准对自动变量(或具有静态存储的变量)的对齐没有要求,除了编译器必须确保访问它们有效。

  • C++03 3.9/5 Types C ++ 03 3.9 / 5类型

Object types have alignment requirements (3.9.1, 3.9.2). 对象类型具有对齐要求(3.9.1,3.9.2)。 The alignment of a complete object type is an implementation-defined integer value representing a number of bytes; 完整对象类型的对齐是表示字节数的实现定义的整数值; an object is allocated at an address that meets the alignment requirements of its object type 在满足其对象类型的对齐要求的地址处分配对象

Note: "object type" here means a type that's not a function, reference or void type, (ie, it applies to unsigned char ). 注意:“对象类型”在这里表示不是函数,引用或void类型的类型(即,它适用于unsigned char )。

One way to get an aligned buffer might be to declare buff like so: 获取对齐缓冲区的一种方法可能是声明buff如下所示:

KEY_VALUE_BASIC_INFORMATION buff[valueNameStructSize/sizeof(KEY_VALUE_BASIC_INFORMATION) + 1];

And you'll be able to get rid of the reinterpret_cast<> to boot. 而且你将能够摆脱reinterpret_cast<>来启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么Qt有标准C ++对象的&#39;Q&#39;版本(例如QVector,QString等)? - Why does Qt have a 'Q' version of standard C++ objects (e.g. QVector, QString, etc.)? 标准是否使用多余的括号定义列表初始化(例如T {{{10}}})? - Does the standard define list initialization with superfluous braces (e.g. T{{{10}}})? C / C ++中的typedef是否真的通过组合复合类型(例如int *)来创建一个NEW类型? - Does typedef in C/C++ really create a NEW type by combining the compound type (e.g. int*)? 除了内容(例如类型,位置)之外,变量是否消耗内存? - does a variable consume memory in addition to just its content (e.g. type, location)? 为什么成员函数需要'&'(例如在std :: bind中)? - Why does a member function needs '&' (e.g. in std::bind)? malloc怎么理解alignment? - how does malloc understand alignment? CMake 是否需要静态库(例如 ZLIB)? - Can CMake require static libraries (e.g., ZLIB)? Visual Studio 代码重构似乎不起作用(例如重命名符号 - f2) - Visual studio code refactoring does not seem to work (e.g. rename symbol - f2) 如何通过内容正则表达式匹配pcap(例如tcpdump)文件? - How does one filter pcap (e.g. tcpdump) files by content regex match? 对没有明显结尾的容器(例如树)实施迭代器是否有意义? - Does it make sense to implement iterators for containers which has no obvious end - e.g. trees?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM