gpt4 book ai didi

c++ - "no base classes of the same type as the first non-static data member"

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:17:27 26 4
gpt4 key购买 nike

asked this a while ago在 comp.std.c++ 上并没有得到答复。
我只是要在那里引用我的帖子,稍作修改。

标准布局类的最后一个要求 9/6 是必要的还是有用的?
提供了脚注解释:

This ensures that two subobjects thathave the same class type and thatbelong to the same most-derived objectare not allocated at the same address(5.10).


单独来看,脚注是不正确的。两个空基类
公共(public)基类可能会产生基类的两个实例
同一个地址。
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};

D d;
static_cast<A*>(static_cast<B*>(&d))
== static_cast<A*>(static_cast<C*>(&d)); // allowed per 1.8/5
在 5.10 的上下文中,子对象仅在
成员指针的比较要求。基础子对象是
无关。此外,它不会使
给一个(标量)指针之间的比较赋予特殊状态的意义
成员子对象和指向上面的基础子对象的指针
指向基本子对象的指针之间的比较。
C++03 中没有这样的限制。即使有一个 ABI 要求每个成员
分配在与任何相同类型的基址不同的地址,但
已经允许对上面的代码进行空基类优化,我
认为 ABI 有问题,标准不应该捕捉到这一点。
语言 goes back to N2172
这表明多重继承可能会引起麻烦并且需要
在标准布局类中不允许使用以确保 ABI compatibility ;
然而,这最终是被允许的,因此要求
没有意义。

供引用,1.8/5-6:

5 Unless it is a bit-field (9.6), amost derived object shall have anon-zero size and shall occupy one ormore bytes of storage. Base classsubobjects may have zero size. Anobject of trivially copyable orstandard-layout type (3.9) shalloccupy contiguous bytes of storage.

6 Unless an object is a bit-field or abase class subobject of zero size, theaddress of that object is the addressof the first byte it occupies. Twodistinct objects that are neitherbit-fields nor base class subobjectsof zero size shall have distinctaddresses.

(footnote) Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference.


补充说明:
10.1/8 指的是与 5.10 相同的神秘内容,但这也只是一个信息说明。

[Note: … A base class subobject may be of zero size (Clause 9); however, two subobjects that have the same class type and that belong to the same most derived object must not be allocated at the same address (5.10). — end note ]


GCC 似乎保证相同类型的空基子对象被赋予唯一的地址。 Example program and output.这似乎足以保证给定类型的对象由地址唯一标识。这将超出 C++ 对象模型第 1.8 节的保证。当然,这是个好主意,但标准似乎并不要求这样做。同样,平台 ABI 可以将此保证扩展到第一个成员别名为空基的类。该语言为 ABI 设定了最低要求;一个 ABI 可以添加语言特性,其他 ABI 可以效仿,标准的追赶过程很容易出错。
我的问题是给定的要求是否在标准的上下文中完成了任何事情,而不是它是否与其他 ABI 保证一致对用户有用。证明这种唯一地址保证是有意的,只是偶然遗漏的证据,也会使要求更有意义。

总结答案(或我的结论,无论如何):
该要求在理论上并不能确保任何事情,因为无论如何都可以确保给定类型的所有对象具有不同的地址。当空基类子对象的地址与另一个对象(另一个基类或成员)冲突时,编译器可以简单地为其分配结构内的任意位置。由于标准布局规则仅描述数据成员的位置(可能是继承的),空基的位置仍然未指定,并且可能在类似的标准布局类之间不兼容。 (据我所知,非空基的位置仍然未指定,然后不清楚在这种情况下“第一成员”是什么意思,但在任何情况下它们都必须保持一致。)
在实践中,该要求允许实现继续使用现有的 ABI,只要它们包括空的基类优化。现有编译器可能会在违反要求时禁用 EBO,以避免基址的地址与第一个成员的地址重合。如果标准没有以这种方式限制程序,库和程序将不得不使用更新的 C++0x 编译器重新编译……不值得!

最佳答案

如果将该等式表达式放在 assert() 中,你会发现它失败了。 A 子对象位于不同的位置。这是不指定 virtual 的正确行为:

struct B : virtual A {};
struct C : virtual A {};

virtual , D 已经不是标准布局类,根据第二条规则。在 C++ '98、'03 和 '0x 中就是这种情况。

编辑以反射(reflect)评论:

再次编辑:没关系,这还不够。

标准布局类定义的重点是指定可以与其他语言一起使用的东西。让我们以 C 为例。在一般情况下,以下 C++ 类
struct X : public B{
B b;
int i;
};

将等同于这个 C 结构:
struct X{
B base;
B b;
int i;
};

如果 B 是一个空类并且应用了空基优化,则 X 将等同于 C 中的这个:
struct X{
B b;
int i;
};

但是,交互的 C 端不会知道该优化。 C++ X 和 C X 的实例将不兼容。该限制阻止了这种情况。

关于c++ - "no base classes of the same type as the first non-static data member",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3902513/

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