C++ visualc&x2B+;不考虑堆栈变量的对齐方式
在使用Visual Studio 16.8.1为x86编译后,以下操作有时会失败:C++ visualc&x2B+;不考虑堆栈变量的对齐方式,c++,visual-c++,C++,Visual C++,在使用Visual Studio 16.8.1为x86编译后,以下操作有时会失败: #include <cassert> #include <cstdint> struct X { uint64_t value; }; int main() { X x; assert(reinterpret_cast<uintptr_t>(&x) % alignof(X) == 0); } #包括 #包括 结构X{uint64_t value;}
#include <cassert>
#include <cstdint>
struct X { uint64_t value; };
int main() {
X x;
assert(reinterpret_cast<uintptr_t>(&x) % alignof(X) == 0);
}
#包括
#包括
结构X{uint64_t value;};
int main(){
X;
断言(重新解释强制转换(&x)%alignof(x)==0);
}
有趣的是,如果X
具有显式对齐说明符:struct alignas(uint64\u t)X
,则不会触发断言
我假定这是编译器错误而不是C++标准的一些怪癖?我是正确的? < P>这是一个bug。
在x86上,除非操作数自然对齐,否则某些操作可能会导致性能下降。显然VisualC++有一个不一致的代码<代码> > <代码>操作符,它返回自然对齐而不是一个类型所需的对齐方式。使用MSVC构建32位时,uint64\u t
/double
的自然对齐为8,而其所需对齐为4。因此,在上面的代码中,x
的地址必须是4的倍数,但不一定是alignof(x)
的倍数
uint64\u t x强调了这种令人困惑的行为代码>与alignas(uint64_t)uint64_t x的含义不同代码>。只有后者具有预期的对齐方式
另请参见:GCC修复了一个类似的和相关的libc++。也许怪癖就在您的期望中。为什么您希望断言成立?我希望x
按照其对齐要求放置在内存中。但是x
的地址只是一些地址,与什么对齐?(顺便说一句,我不知道这里发生了什么,我只是好奇并期待答案)结构的对齐要求是32位构建中的32位。与地址0
对齐。如果x
具有对齐方式N
,我希望它的地址是N
.Reported.Documented的倍数。谢谢链接。这解释了x86上堆栈变量的对齐方式。但是它没有处理alignof
,它应该报告所需的4的对齐。