web-dev-qa-db-ja.com

C ++およびCでのユニオンの初期化

次のように定義されたヘッダーファイルに、定数を使用するCライブラリを作成しました。

typedef struct Y {
  union {
    struct bit_field bits;
    uint8_t raw[4];
  } X;
} CardInfo;

static const CardInfo Y_CONSTANT = { .raw = {0, 0, 0, 0 } };

.raw初期化子はCのみの構文です。

CおよびC++で使用できるように、ユニオンを含む定数を定義するにはどうすればよいですか。

28
Alex

同じ問題がありました。 C89の場合、次のことが当てはまります。

C89スタイルの初期化子では、構造体メンバーは宣言された順序で初期化する必要があり、共用体の最初のメンバーのみを初期化できます

この説明は次の場所にありました: 構造体および共用体の初期化

15
hae

C++ 11を使用すると、次のように独自のコンストラクタを作成できると思います。

union Foo
{
    X x;
    uint8_t raw[sizeof(X)];

    Foo() : raw{} { }
};

これは、すべての要素がゼロで初期化されたアクティブなメンバーFooを持つraw型の共用体をデフォルトで初期化します。 (C++ 11より前は、完全なオブジェクトではない配列を初期化する方法はありませんでした。)

4
Kerrek SB

私は次の道を選ぶことにしました。

  • .member初期化を使用しないでください。
  • メンバーのstatic const struct Foobar初期化を使用しないでください

代わりに、グローバル変数を宣言します。

extern "C" {
  extern const struct Foobar foobar;
}

グローバルセクションで初期化します。

struct Foobar foobar = { 0, 0, 0, 0 };

そして、C++コンパイラを最新のANSI C99構文でバグ修正する代わりに、リンカにCシンボルのデマングル作業を行わせました。

2
Alex