gpt4 book ai didi

c++ - gcc/clang 在基本结构的后填充中布置派生结构的字段

转载 作者:可可西里 更新时间:2023-11-01 18:35:43 25 4
gpt4 key购买 nike

<分区>

当涉及填充和继承时,我对 gcc 和 clang 如何布局结构感到困惑。这是一个示例程序:

#include <string.h>
#include <stdio.h>

struct A
{
void* m_a;
};

struct B: A
{
void* m_b1;
char m_b2;
};

struct B2
{
void* m_a;
void* m_b1;
char m_b2;
};

struct C: B
{
short m_c;
};

struct C2: B2
{
short m_c;
};

int main ()
{
C c;
memset (&c, 0, sizeof (C));
memset ((B*) &c, -1, sizeof (B));

printf (
"c.m_c = %d; sizeof (A) = %d sizeof (B) = %d sizeof (C) = %d\n",
c.m_c, sizeof (A), sizeof (B), sizeof (C)
);

C2 c2;
memset (&c2, 0, sizeof (C2));
memset ((B2*) &c2, -1, sizeof (B2));

printf (
"c2.m_c = %d; sizeof (A) = %d sizeof (B2) = %d sizeof (C2) = %d\n",
c2.m_c, sizeof (A), sizeof (B2), sizeof (C2)
);

return 0;
}

输出:

$ ./a.out
c.m_c = -1; sizeof (A) = 8 sizeof (B) = 24 sizeof (C) = 24
c2.m_c = 0; sizeof (A) = 8 sizeof (B2) = 24 sizeof (C2) = 32

结构 C1 和 C2 的布局不同。在 C1 中,m_c 分配在结构 B1 的后填充中,因此被第二个 memset () 覆盖;使用 C2 它不会发生。

使用的编译器:

$ clang --version
Ubuntu clang version 3.3-16ubuntu1 (branches/release_33) (based on LLVM 3.3)
Target: x86_64-pc-linux-gnu
Thread model: posix

$ c++ --version
c++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

-m32 选项也是如此(显然,输出的大小会有所不同)。

Microsoft Visual Studio 2010 C++ 编译器的 x86 和 x86_64 版本都没有这个问题(即它们对结构 С1 和 C2 的布局相同)

如果这不是错误并且是设计使然,那么我的问题是:

  1. 分配或不分配派生结构字段的精确规则是什么在 back-padding 中(例如,为什么它不会发生在 C2 上?)
  2. 有没有什么方法可以用开关/属性覆盖此行为(即像 MSVC 一样布局)?

提前致谢。

弗拉基米尔

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com