c++ - 该标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如,如 malloc 那样)?

标签 c++ windows visual-c++

我很好奇是否需要在堆栈上分配缓冲区以正确对齐任何类型,类似于 malloc 的工作方式,或者我是否会被迫使用类似 的东西std::aligned_storage.

考虑以下代码块:

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;
}

请注意值 buff 是如何放置在堆栈上的字符缓冲区,其大小可容纳给定的最大数据量。但是,我担心如果将此代码移植到另一个(例如 ARM 或 IA64)平台,则将缓冲区解释为字符串所需的转换可能会导致对齐错误。

编辑:如果有人好奇,我根据 std::aligned_storagestd::alignment_of 重做了这个:

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);
}

最佳答案

该标准对自动变量(或具有静态存储的变量)的对齐没有任何要求,除了编译器必须确保访问它们有效。

  • C++03 3.9/5 类型

Object types have alignment requirements (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

注意:这里的“对象类型”是指不是函数、引用或 void 类型的类型(即,它适用于 unsigned char)。

获得对齐缓冲区的一种方法可能是声明 buff像这样:

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

你将能够摆脱 reinterpret_cast<>启动。

关于c++ - 该标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如,如 malloc 那样)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9831445/

相关文章:

c++ - 使用 C++ 的词法分析器

c++ - Visual Studio 2012 : “Apply Code Changes” is disabled C++

python - 如何在 Windows 中安全地存储数据库凭据?

windows - 真正杀死Windows中的进程

c++ - MSVC 编译器错误 C2688 : Microsoft C++ ABI corner case issue?

c++ - 在 midl 生成的头文件中定义一个结构

visual-c++ - MSVC 预处理器 - 如何使用编译器宏输出定义值?

C++:理解动态数组

c++ - C++ 中的二叉树基础知识

python - 如何停止在 Python 中播放的声音?