繁体   English   中英

零大小的结构

[英]Zero-sized struct

根据C ++标准(继承自C),空结构仍然具有非零大小。 这个(可怜的恕我直言)的原因是两个不同的变量应该有不同的地址。 现在,继承一个空结构并不总是“膨胀”该对象。 但在某些情况下情况就是这样。

我有一个相当复杂的类架构,涉及激烈的模板巫术。 结果,最后的类(我需要创建的实例)可能有几个继承的空结构。 由于这个事实,他们中的一部分最终可能会被夸大。 最糟糕的是,他们的内存布局实际上取决于继承的顺序。

如果有可能的话,我想摆脱这一切。

是否有一个C ++编译器可以配置为消除这种空间浪费,实际上是打破标准的代价?

编辑:

我是说这个:

struct Empty1 {};
struct Empty2 {};

struct NonEmpty {
    int Value;
};

struct MyClass1
    :public NonEmpty
    ,public Empty1
    ,public Empty2
{
};

struct MyClass2
    :public Empty1
    ,public NonEmpty
    ,public Empty2
{
};

struct MyClass3
    :public Empty1
    ,public Empty2
    ,public NonEmpty
{
};

STATIC_ASSERT(sizeof(MyClass1) == 8);
STATIC_ASSERT(sizeof(MyClass2) == 4);
STATIC_ASSERT(sizeof(MyClass3) == 8);

不仅空结构会使对象膨胀(当多个这样的东西继承时),而且结果还取决于空结构的继承顺序。

空基优化是允许空基不要“膨胀”对象的东西,就像你调用它一样。 但是,您必须小心,以便对象不会从同一个空基继承两次,否则将不允许此优化。 避免这种情况的一种方法是对空基础进行模板化,实例化它们,以便不会多次继承相同的空模板实例。

如果您的基类用于标记具体类,那么您可以考虑将您的设计更改为非侵入式设计。

在大多数现代c ++编译器中,您会发现:

struct a { }; // empty struct
struct b : a { int x}; // inherits from empty struct.

assert(sizeof(b)==sizeof(int)); // despite sizeof(a) >0

这实际上是否能缓解您的顾虑?

是否有可以配置的C ++编译器来消除这种空间浪费,......

是。 GCC-4.3.4

......实际上打破了标准的代价?

不,该标准允许您期望的行为。

g ++支持零大小数组,您可以使用以下之一:

struct Empty1 {
  int dummy[0];
};

要么

struct Empty2 {
  int dummy[];
};

只有在使用'-pedantic'标志时,它才会生成警告。

如果您已经说过,它将具有与同一对象中相同类型的另一个实例相同的地址,则基类可以是非零大小。

要“解决”这个问题,你需要确保你继承另一个类的空类或结构没有任何共同的祖先。

或者您可以自己手动布置类,但听起来您正在执行类似于从DirectX顶点声明枚举创建DirectX顶点类型的操作,因此这实际上没有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM