【问题标题】:VS2019 alignas in struct definition overrules pragma pack结构定义中的 VS2019 alignas 推翻了 pragma pack
【发布时间】:2021-02-05 17:07:09
【问题描述】:

我正在尝试使用#pragma pack 打包结构“测试”。

在 VS2019 16.7.2 中,以下静态断言失败。

struct alignas(4 * sizeof(float)) Vec4
{
    float x,y,z,w;
};

#pragma pack(push,1)
struct Test
{
    char f;
    Vec4 vec;
};
#pragma pack(pop)

static_assert(sizeof(Test) == sizeof(char) + sizeof(Vec4), "Incorrect size.");

Test 的大小为 2*sizeof(Vec4),这表明 struct 定义本身的 alignas 超过了 pack。

静态断言在 GCC 10.2 或 Clang 11.0.0 中不会失败。

有谁知道根据需要打包 Test 的方法? (不改变 Vec4 结构的对齐方式)

谢谢。

【问题讨论】:

  • "根据需要打包测试?(不改变 Vec4 结构的对齐方式)" --> 更改顺序:vec 然后f 可能会起作用。嗯
  • 认为这是预期的行为,沿着同一行as "当遇到多个 alignas 说明符时,编译器将选择最严格的一个,(具有最大值的那个)* .

标签: c++ c++11 visual-c++


【解决方案1】:

#pragmas 是实现定义的。 ISO C++ 标准只对它们这么说:

Pragma 指令 [cpp.pragma]

表单的预处理指令

# pragma pp-tokensoptnew-line

使实现以实现定义的方式运行 方式。该行为可能会导致翻译失败或导致 翻译器或生成的程序以不合格的方式运行 方式。任何未被实现识别的编译指示都是 忽略。

因此,GCC 或 Clang 以某种方式实现 #pragma pack 是无关紧要的,显然 VC++ 以将 alignas 指令考虑在内的方式实现 #pragma pack。在警告级别 4 时,它甚至会发出警告:

警告C4324:“测试”:由于对齐说明符而填充了结构

MSDN 进一步says那个

如果没有__declspec(align(#)),编译器通常会根据目标处理器和数据大小在自然边界上对齐数据,在 32 位处理器上最多 4 字节边界,在 64 位处理器上最多 8 字节边界.类或结构中的数据在类或结构中以其自然对齐和当前打包设置(来自#pragma pack/Zp 编译器选项)的最小值对齐。

这表明#pragma pack 只会影响默认对齐方式,而alignas 会覆盖它。和

__declspec(align(#))只能增加对齐限制。

因此,似乎一旦将alignas 设置为Vec416,它就不能减少(不改变Vec4 结构的声明)。

【讨论】:

  • 感谢您的回复。我确实知道包装不是标准的一部分。你知道是否有另一种方法可以实现我想要的“测试”布局?
猜你喜欢
  • 2013-09-29
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 2014-05-10
  • 2012-03-15
相关资源
最近更新 更多