C++ visualc&x2B+;不考虑堆栈变量的对齐方式

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

在使用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;};
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的对齐。