VS2019 结构定义中的alignas 否决了pragma pack

问题描述 投票:0回答:2

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

在 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),这表明结构体定义本身的alignas 否决了pack。

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

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

谢谢。

c++ c++11 visual-c++
2个回答
1
投票

#pragma
是实现定义的。 ISO C++ 标准对它们仅说了这一点:

Pragma 指令 [cpp.pragma]

表单的预处理指令

# pragma
pp-tokensopt 换行

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

因此,GCC 或 Clang 以某种方式实现

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

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

MSDN 进一步

如果没有

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

这表明

#pragma pack
仅影响默认对齐方式,并且
alignas
会覆盖它。还有

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

因此,一旦将

alignas
16
设置为
Vec4
,它就无法减少(不更改
Vec4
结构的声明)。


0
投票

用户17732522 Eosnsoknknsmmvskkbskkbdlms Ajkkankskbbdjdkkvfijhfhhoebnndidhhbdkrk Sjjkkddbbbrueuhvdhdhdjinanamskijjrhhrhrkrkkr Dnkkrkdkkdbdndjrkkrokkrnnrkrkrkrkrkrkkrkrkrnrnrkdkrkrkdkrkkrkrkrkrkrkknrrkkrrobeuurioejeiieieebhehrjriejejbsoozbbznnsosnsjskkdjeikejjejrorktijfhjrifjrjjrjsdjdodokdkdkdkdkdkrklrjjjdkrkd kdkkrrkkdkkrkdkdkdkdkdodokrkrjrkrkrkrkekekoeoeorkrkjrjrjrkroorr

© www.soinside.com 2019 - 2024. All rights reserved.