是多级“结构继承"吗?保证到处工作? [英] Is multiple-level "struct inheritance" guaranteed to work everywhere?

查看:28
本文介绍了是多级“结构继承"吗?保证到处工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在 C 中,结构的第一个成员保证在它之前没有填充.因此 &mystruct == &mystruct.firstmember 始终为真.

I know that in C, the first member of a struct is guaranteed to have no padding before it. Thus &mystruct == &mystruct.firstmember is always true.

这允许结构继承"技术,如本问题所述::>

This allows the "struct inheritance" technique, as described in this question:

typedef struct
{
    // base members

} Base;

typedef struct
{
    Base base;

    // derived members

} Derived;

// ... later
Base* object = (Base*) malloc(sizeof()); // This is legal

但是,我想确保这实际上可以通过无限的继承"层安全地工作.例如:

However, I'd like to make sure that this actually works safely with unlimited layers of "inheritance". E.g.:

typedef struct
{
    // members

} A;

typedef struct
{
    A base;

    // members

} B;

typedef struct 
{
    B base;

    // members
} C;

是否保证以下所有用途都有效?

Are all of the following uses guaranteed to work?

A* a = (A*) malloc(sizeof(B));
A* a = (A*) malloc(sizeof(C));
B* b = (B*) malloc(sizeof(C));
C* c = malloc(sizeof(C));

// ... use and access members through the pointers

让我澄清一下我在问什么.以下使用多级继承"是否保证按 C 标准工作?

Let me clarify what I'm asking. Is the following use of "multi-level inheritance" guaranteed to work by the C standard?

C* c = malloc(sizeof(C));
// ... initialize fields in c

A* a = (A*) c;
// ... use A fields in a

B* b = (B*) a;
// ... use B fields in b

B* b = (B*) c;
// ... use B fields in b

c = (C*) a;
// ... go back to using C fields in c

推荐答案

您描述的那种多级继承"必须遵循相同的原则——在您引用的其他问答中解释——使这种继承完全起作用.具体而言,该标准明确规定,在适用类型之间转换结构及其初始成员的地址具有预期效果:

That the kind of "multi-level inheritance" you describe must work follows from the same principles -- explained in the other Q&A you referenced -- that makes this kind of inheritance work at all. Specifically, the standard explicitly provides that casting the addresses of structures and of their initial members between the applicable types has the desired effect:

一个指向结构对象的指针,适当的转换后,指向其初始成员 [...],反之亦然.

A pointer to a structure object, suitably converted, points to its initial member [...] and vice versa.

(第 6.7.2.1/15 段)

(paragraph 6.7.2.1/15)

所以考虑这个声明,相对于提供的结构定义:

So consider this declaration, relative to the structure definitions provided:

C c;

引用的条款指定 &c == (C *) &c.base(B *) &c == &c.base 都是真的.

The quoted provision specifies that &c == (C *) &c.base and (B *) &c == &c.base are both true.

但是c.base是一个B,所以规定还指定了(A *) &c.base == &c.base.base&c.base == (B *) &c.base.base 都是真的.

But c.base is a B, so the provision also specifies that (A *) &c.base == &c.base.base and &c.base == (B *) &c.base.base are both true.

因为 (B *) &c == &c.base 为真并且 &c.base == (B *) &c.base.base 都是真的,因此 (B *) &c == (B *) &c.base.base 也是真的.

Since (B *) &c == &c.base is true and &c.base == (B *) &c.base.base are both true, it follows that (B *) &c == (B *) &c.base.base is also true.

将两边都转换为 A *C * 然后也会产生等式 (A *) &c == &c.base.base&c == (C *) &c.base.base.

Casting both sides to either A * or C * then produces also the equalities (A *) &c == &c.base.base and &c == (C *) &c.base.base.

这种推理可以扩展到任意嵌套深度.

This reasoning can be extended to an arbitrary nesting depth.

人们可以在相对于严格的别名规则中对动态分配的结构进行一些狡辩,但没有理由认为在这种情况下它应该以任何不同的方式工作,只要一个首先通过最具体类型的左值(在本例中为 C)访问动态分配的空间,我看到没有任何场景支持对动态分配情况的标准的不同解释,而不是适用于其他情况.在实践中,我不希望任何实现实际上都需要通过最具体的类型进行初始访问.

One can quibble a bit about dynamically allocated structures vis a vis the strict aliasing rule, but there's no reason to think that it is supposed to work any differently in that case, and as long as one first accesses the dynamically-allocated space via an lvalue of the most specific type (C in this example), I see no scenario that supports a different interpretation of the standard for the dynamic-allocation case than applies to other cases. In practice, I do not expect initial access via the most specific type actually to be required by any implementation.

这篇关于是多级“结构继承"吗?保证到处工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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