首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GCC的“空基优化”是可配置的吗?

GCC的“空基优化”是可配置的吗?
EN

Stack Overflow用户
提问于 2009-02-13 19:17:50
回答 3查看 1.7K关注 0票数 9

请考虑以下类型:

代码语言:javascript
运行
复制
  struct A {};
  struct B : A { int i; };

标准要求的sizeof(A) > 0

由于空基优化,sizeof(B)应为4。然而,在GCC 4.1.1上是5(我在这方面使用的是1包)。而且不一致-我的一些文件得到了它,一些没有。还不能确定有什么不同,我们有一个很大的问题。

在我使用的其他三个编译器(微软和飞思卡尔)上,我没有这个问题。根据this article的说法,空基优化显然是可选的。

在GCC 4.1.1中有没有编译器选项或编译指示来调优这一点?我可以解决这个问题,但我想先了解发生了什么。我用谷歌搜索了一段时间,似乎什么也找不到。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-02-13 19:57:36

这总是会发生的。在我弄清楚之前,我会立即发帖。也许张贴的行为让我以一种不同的方式思考。

因此,在我的问题中,示例有点过于简单。实际上更像是这样:

代码语言:javascript
运行
复制
struct Base {};
struct C1 : Base { int i; }
struct C2 : Base { C1 c; int i; }

sizeof(C1)在所有平台上都是正确的4,但是sizeof(C2)在GCC上是9而不是8。还有..。很明显,根据我在原问题中链接的文章的最后一点,唯一正确的事情就是GCC。我将在这里引用它(来自Nathan Meyer):

根据编译器必须遵守的ABI规范,可以进行一整套相关的“空子对象”优化。(几年前,杰森·梅里尔向我指出了其中一些问题。)例如,考虑三个(空)类型A、B和C的结构成员,以及第四个非空成员。顺理成章地,它们都可以占用相同的地址,只要它们彼此之间或与包含类没有任何共同的基础。在实践中,一个常见的陷阱是让类的第一个(或唯一)成员派生自与类相同的空基。编译器必须插入填充,以便这两个子对象具有不同的地址。这实际上发生在具有interator成员的迭代器适配器中,这两个成员都派生自std::iterator。一个不小心实现的标准std::reverse_iterator可能会出现这个问题。

所以,我看到的不一致只发生在我有上述模式的情况下。我从一个空结构派生的其他地方都没问题。

工作起来很容易。感谢大家的评论和回答。

票数 11
EN

Stack Overflow用户

发布于 2009-05-28 07:53:42

使用标准填充时,GCC C++遵循以下规则:

注:__attribute__((__packed__))或更改默认装箱将修改这些规则。

  • 类EmptyBase {};--> parenting).
  • Non (EmptyBase) == 1
  • 任何数量的空基都会映射到结构偏移量中的0,只要它们都是唯一的类型(包括sizeof(Sizeof)==1
  • )。
  • 如果紧跟在空基后面的派生类的第一个成员不是从这些基中的任何一个派生的,允许从大于或等于空基地址的该成员的第一个正确对准的偏移量开始--这可以是与紧跟在空基后面的派生类的第一个成员从那些基中的任何一个导出的empty-bases.
  • If相同的地址,它将从该成员的第一个正确对齐的偏移量开始,该偏移量大于空基地址-这永远不会与为空的empty-bases.
  • Members地址相同-类在包含类中至少占用一个字节的存储空间。

MSVC++遵循以下规则:

注:#pragma pack或更改默认装箱将修改这些规则。

  • 类EmptyBase {};--> sizeof(EmptyBase) == 1
  • 空基类(或从空基派生的类)从偏移量0(零)开始的唯一方式是它是第一个基类。
  • 非空基类将从基类的下一个有效对齐偏移量开始。
  • 所有空基类在派生类中的有效存储空间为零,并且不影响当前偏移量,除非后面跟着另一个空基类(或从空基派生的类),在这种情况下你应该看到下面的规则。
  • 一个跟在空基类(或从空基派生的类)后面的空基类(或从空基派生的类)在填充到类的正确对齐之前会在当前的偏移量位置上加1。
  • 在最后一个基类和第一个类成员或vft指针之间没有填充(除了为了对齐)。*注意:这是一种过于激进的空基优化,可能会破坏为空的C++类-类在包含类中至少占用一个字节的存储空间。
票数 3
EN

Stack Overflow用户

发布于 2009-02-13 19:44:37

这并不是一个完整的答案,但是GCC Manual提到g++有时会将空的基类放在错误的偏移量上。请参阅关于-Wabi选项的部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/547290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档