标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如malloc)
Does the standard require that objects in automatic storage have the correct alignment for any type (e.g. as malloc does)?
我很好奇是否需要在堆栈上分配缓冲区来对任何类型进行正确对齐,类似于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_storage
和std::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类型
对象类型具有对齐要求(3.9.1、3.9.2)完整对象类型的对齐是定义的实现表示字节数的整数值;分配了一个对象在满足其对象类型的对齐要求的地址
注意:这里的"对象类型"是指不是函数、引用或void类型的类型(即,它适用于unsigned char
)。
获得对齐缓冲区的一种方法可能是这样声明buff
:
KEY_VALUE_BASIC_INFORMATION buff[valueNameStructSize/sizeof(KEY_VALUE_BASIC_INFORMATION) + 1];
您将能够摆脱reinterpret_cast<>
进行引导。
相关文章:
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 具有调整对齐方式的类型定义
- size_t的大小和对齐方式是否与ptrdiff_t相同?
- 逗号运算符在对齐方式中
- vcpkg:指定结构成员对齐方式
- 使用字节数组具有单字节对齐方式的结构是否安全
- C++对齐方式(何时使用对齐方式)
- 编译器会秘密增加结构的对齐方式吗?
- C++17 中函数参数的指针对齐方式
- 未在此范围内声明的对齐方式?
- 如何控制 clang 格式新行中 lessless 的对齐方式
- C++ 编译器正在更改我的结构的对齐方式.我怎样才能防止这种情况
- 是否有符合标准的方法来确定非静态杆件的对齐方式?
- 重载运算符是具有较小默认对齐方式的新增运算符
- 结构和对齐方式的大小
- Sizeof 舍入到对齐方式,但编译器仍将对象放在剩余的字节中
- 是否可以让 std::vector<char> 使用选定的内存对齐方式分配内存
- 对齐方式与指针中尾随零的数量有何关系
- 对齐方式究竟如何影响内存布局和新放置的巴哈维?
- 幻影类型是否与原始类型具有相同的对齐方式