【发布时间】:2020-03-11 00:17:55
【问题描述】:
以下代码在 MSVC 与 clang/gcc 上的内存中生成不同的布局。为什么?
#include <stdio.h>
#pragma pack(push,1)
struct empty_struct
{
};
class derived_struct : public empty_struct
{
int m_derivedMember;
};
class derived_struct_container : public empty_struct
{
public:
derived_struct m_ds;
};
class foo
{
public:
foo() {}
derived_struct_container m_dsc;
int m_foo_member;
};
#pragma pack(pop)
int main()
{
foo fb;
printf("pf->m_dsc offset: %ld\n", (char *)&fb.m_dsc - (char *)&fb);
printf("pf->m_dsc.m_ds offset: %ld\n", (char *)&(fb.m_dsc.m_ds) - (char *)&fb);
printf("pf->m_foo_member offset: %ld\n", (char *)&(fb.m_foo_member) - (char *)&fb);
return 0;
}
MSVC x64 上的输出是:
fb.m_dsc offset: 0
fb.m_dsc.m_ds offset: 0
fb.m_foo_member offset: 4
Linux下clang x64上的输出为:
fb.m_dsc offset: 0
fb.m_dsc.m_ds offset: 1
fb.m_foo_member offset: 5
如何让 clang 布局与 MSVC 布局相匹配?
【问题讨论】:
-
因为这是实现定义的行为。 C++ 标准不需要任何实现的任何特定结果。 gcc.gnu.org/onlinedocs/gcc/… 似乎表明无法更改此 gcc 行为。
-
clang 和 gcc 都在 Windows 和 Linux 上运行,这将有助于在您的问题中澄清这一点,而不是将编译器和操作系统混为一谈。还要提供目标的详细信息,因为 x64 ABI 不同于 32 位 ABI
-
如果您在 Windows 系统上,您可以得到真正的 hacky 并向
derived_struct_container添加一个预处理器指令,该指令将单个char放入结构中。也就是说,你没有。除了学术好奇心之外,还有其他目的吗? -
我在 Windows 中得到输出
0 1 5(g++ 9.2.0 目标 x86_64-w64-mingw32,目标 i686-w64-mingw32 相同)
标签: c++ windows clang pragma pragma-pack