2

C11 標準では、単一のユニオン内にネストされた構造体によって共有される共通の初期シーケンスの次の定義があります。

6.5.2.3/6

共用体の使用を簡素化するために、1 つの特別な保証が行われます。共用体に、共通の初期シーケンス (以下を参照) を共有する複数の構造体が含まれている場合、および共用体オブジェクトに現在これらの構造体の 1 つが含まれている場合、共通の構造体を検査することが許可されます。それらのいずれかの最初の部分は、共用体の完全な型の宣言が表示される場所であればどこでも使用できます。対応するメンバーが 1 つ以上の初期メンバーのシーケンスに対して互換性のある型 (およびビット フィールドの場合は同じ幅) を持っている場合、2 つの構造体は共通の初期シーケンスを共有します。

例 3 以下は有効なフラグメントです。

union {
    struct {
        int alltypes;
    } n;

    struct {
        int type;
        int intnode;
    } ni;

    struct {
        int type;
        double doublenode;
    } nf;
} u;

u.nf.type = 1;
u.nf.doublenode = 3.14;
/* ... */
if (u.n.alltypes == 1)
        if (sin(u.nf.doublenode) == 0.0)
            /* ... */

ただし、この記事の理解によると、上記のコードは無効です。

In the outer if statement we indicate that n::alltypes data member is active (simultaneously with ni::type and nf::type as the standard states) yet in the inner if we use nf::doublenode which is not a part of the common initial sequence.

Can somebody clarify this issue?

4

1 に答える 1

4

[共通の初期シーケンスを共有するいくつかの構造] の共通の初期部分を検査することは許可されています

提供された例を使用すると、仕様のこの部分は、の可能な各メンバー型が初期フィールドとして をunion持っているため、変数が初期化/使用されたでも、メンバー型のいずれかintを使用してその共通の初期フィールドにアクセスできることを示しています。特定のメンバー タイプの 1 つとして。

これはまさにこの例が行うことです:後続のフィールドを として初期化した後、 anのメンバーintとして初期値にアクセスし、次にすべて同じ変数を使用してan のフィールドにアクセスします。alltypesnnfdoublenodenf

可能な型の 1 つとしてを使用してunionも、ある種の構造に強制されるわけではありません。これが共用体の仕組みです。

この保証はしばらく前から存在していたことに注意してください。本質的に同じテキストがANSI 仕様のセクション: 3.3.2.3 構造体と共用体のメンバー にあります。

于 2012-08-28T18:05:06.697 に答える