【问题标题】:Visual C++ not respecting alignment for stack variablesVisual C++ 不考虑堆栈变量的对齐方式
【发布时间】:2021-02-28 01:43:42
【问题描述】:

使用 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 有明确的对齐说明符:struct alignas(uint64_t) X,则断言不会触发。

我认为这是编译器错误而不是 C++ 标准的一些怪癖是否正确?

【问题讨论】:

  • 也许这个怪癖在您的期望中。为什么您希望断言成立?
  • 我希望 x 按照对齐要求放置在内存中。
  • 但是x的地址只是一些地址,对齐是什么? (顺便说一句,我不知道这里发生了什么,我只是好奇并期待答案)
  • 在 32 位构建中结构的对齐要求是 32 位。
  • 与地址 0 对齐。如果x 与N 对齐,我希望它的地址是N 的倍数。

标签: c++ visual-c++


【解决方案1】:

这是一个错误。

在 x86 上,除非操作数自然对齐,否则某些操作可能会导致性能损失。显然 Visual C++ 有一个不一致的 alignof 运算符,它返回 natural 对齐而不是 required 对齐类型。使用 MSVC 构建 32 位时,uint64_t/double 的自然对齐方式为 8,而其要求的对齐方式为 4。所以在上面的代码中,x 的地址必须是 4 的倍数,但不是必须是alignof(X) 的倍数。

uint64_t x; 强调了这种令人困惑的行为,其含义与alignas(uint64_t) uint64_t x; 不同。只有后者具有预期的对齐方式。

另请参阅:GCC 修复了类似的 bug 和关联的 libc++ updates。

【讨论】:

  • 举报here。
  • 记录在案的here。
  • 感谢您的链接。这解释了 x86 上堆栈变量的对齐方式。但它没有解决alignof,它应该报告4的必需对齐。
猜你喜欢
  • 1970-01-01
  • 2023-01-03
  • 2011-04-13
  • 2011-07-05
  • 1970-01-01
  • 2010-10-24
  • 2021-07-26
  • 2019-06-27
  • 1970-01-01
相关资源
最近更新 更多