7

私は構造体を持っています:

typedef struct _n
{
    int type;
    union {
        char *s;
        int i;
    };
} n;

次のような複合リテラルを割り当てようとすると、

node n1 = {1, 0};
node n2 = {2, "test"};

gcc は次のような警告を表示します。

warning: initialization makes pointer from integer without a cast
warning: initialization from incompatible pointer type

あいまいな可能性のある型に値を代入するだけで、コンパイラが確信を持てないことは明らかです。ただし、より正確に指定しようとしても、次のようになります。

node n0 = {type: 1, i: 4};

私は得る:

error: unknown field ‘i’ specified in initializer

(union <union name>)前に置くとうまくいくかもしれないと読んだことi:があります。しかし、私は匿名の組合を持つことを好みます。それを行う方法はありますか?

4

1 に答える 1

9

無名共用体は標準 C ではなく、コンパイラの拡張機能です。組合に名前を付けることを強くお勧めします。無名共用体の使用を主張する場合は、その最初の要素に対してのみ初期化子を指定できます。

node n0 = {1, 0};  // initializes `s' to 0

でコンパイルすると-Wall -Wextra -pedantic、gcc は「イニシャライザを囲む括弧がありません」という警告を出しましたが、これは有効な警告です。イニシャライザは、実際には次のように指定する必要があります。

node n0 = {1, {0}};  // initializes `s' to 0

現在、これは「ISO C は名前のない構造体/共用体をサポートしていません」という警告のみを表示します。

ユニオンに名前を付けると、指定イニシャライザと呼ばれる C99 機能を使用して、ユニオンの特定のメンバーを初期化できます。

typedef struct
{
    int type;
    union {
        char *s;
        int i;
    } value;
} node;

node n0 = {1, { .s = "string" }};
node n1 = {2, { .i = 123 }};

ユニオンに名前を付ける必要があります。そうしないと、コンパイラは内部の指定された初期化子について文句を言います。

使用しようとしたnode n0 = {type: 1, i: 4}構文は無効な構文です。指定された初期化子を使用しようとしていたようです。

于 2009-12-11T05:18:58.953 に答える