[英]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_storage
和std::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. 该标准对自动变量(或具有静态存储的变量)的对齐没有要求,除了编译器必须确保访问它们有效。
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.