是“空基础优化"吗?在GCC中可配置? [英] Is the "empty base optimization" in GCC configurable?

查看:72
本文介绍了是“空基础优化"吗?在GCC中可配置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下类型:

  struct A {};
  struct B : A { int i; };

sizeof(A) > 0符合标准要求.

sizeof(B)由于基本优化为空,因此应为4.但是在GCC 4.1.1上它是5(我在该区域使用一包1).而且前后不一致-我的某些文件正在获取文件,有些则没有.尚不能确定有什么区别,我们有很大的经验.

sizeof(B) should be 4 due to the empty base optimization. Yet on GCC 4.1.1 it's 5 (I'm using a pack of 1 in this area). And inconsistently - some of my files are getting it, some are not. Can't be sure what the differences are yet, we have a large prjoect.

在我正在使用的其他三个编译器上(Microsoft和Freescale),我没有这个问题.根据本文.

On the other three compilers I'm using (by Microsoft and Freescale), I don't have this problem. The empty base optimization is optional apparently, according to this article.

在GCC 4.1.1中是否有编译器选项或编译指示来对此进行调整?我可以解决此问题,但我想先了解一下情况.我用Google搜索了一段时间,但似乎找不到任何东西.

Is there a compiler option or pragma to tune this in GCC 4.1.1? I can work around the issue but I would like to understand what's going on first. I Googled for a while and can't seem to find anything.

推荐答案

这总是会发生.我会在发现之前立即发布.也许发布的行为使我以不同的方式思考..

This always happens. I post immediately before I figure it out. Maybe the act of posting gets me thinking in a different way..

所以在我的问题中,样本有点过分简化了.实际上更像是这样:

So in my question the sample was a little bit over-simplified. It's actually more like this:

struct Base {};
struct C1 : Base { int i; }
struct C2 : Base { C1 c; int i; }

在所有平台上,

sizeof(C1)正确为4,但在GCC上,sizeof(C2)为9,而不是8.而且...根据我在原始问题中链接的文章的最后一部分,显然GCC是唯一正确的方法.我在这里引用(内森·迈耶斯的话):

sizeof(C1) is correctly 4 on all platforms, but sizeof(C2) is 9 instead of 8 on GCC. And... apparently GCC is the only thing that gets it right, according to the last bit of the article I linked to in the original question. I'll quote it (from Nathan Meyers) here:

可以进行整个系列的相关空子对象"优化,但要遵循编译器必须遵守的ABI规范. (几年前,Jason Merrill向我指出了其中的一些.)例如,考虑三个(空)类型A,B和C的结构成员,以及第四个非空.一致地,只要它们彼此之间或与包含类之间没有任何共同的基础,它们可能都占据相同的地址. 实践中常见的陷阱是让类的第一个(或唯一)成员派生自与该类相同的空基.编译器必须插入填充,以便它们两个子对象具有不同的地址.这实际上发生在具有interator成员的迭代器适配器中,这两个适配器都从std :: iterator派生.谨慎执行的标准std :: reverse_iterator可能会出现此问题.

A whole family of related "empty subobject" optimizations are possible, subject to the ABI specifications a compiler must observe. (Jason Merrill pointed some of these out to me, years back.) For example, consider three struct members of (empty) types A, B, and C, and a fourth non-empty. They may, conformingly, all occupy the same address, as long as they don't have any bases in common with one another or with the containing class. A common gotcha in practice is to have the first (or only) member of a class derived from the same empty base as the class. The compiler has to insert padding so that they two subobjects have different addresses. This actually occurs in iterator adapters that have an interator member, both derived from std::iterator. An incautiously-implemented standard std::reverse_iterator might exhibit this problem.

因此,我所看到的不一致只是在我具有上述模式的情况下.我从一个空结构派生的每个其他地方都还可以.

So, the inconsistency I was seeing was only in cases where I had the above pattern. Every other place I was deriving from an empty struct was ok.

足够容易解决.谢谢大家的评论和回答.

Easy enough to work around. Thanks all for the comments and answers.

这篇关于是“空基础优化"吗?在GCC中可配置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆