3

関数で無名共用体を宣言すると…</p>

void f(int in) {
    union { int i; float f; };
    // …
}

…それを初期化するための構文は存在しますか (別のステートメントに代入する以外if?

// Nope:
union { int i = in; float f; };
union { int i; float f; } = in;
union { int i; float f; } = {in};
union { int i; float f; }{in};
union { int i; float f; }(in);
4

2 に答える 2

2

以下の更新を参照してください。これが言語の制限なのか、コンパイラの制限なのかはわかりません。

指定された初期化子がない場合 (1999 年に C に追加され、私の知る限り C++ には存在しません)、共用体の初期化子は最初の名前付きメンバーの値のみを指定できます。

union { int i; float f; } obj = { 42 }; // sets obj.i to 42

C は、1999 年標準の時点で、好きな名前付きメンバーを初期化できる指定された初期化子を提供します。

union { int i; float f; } obj = { .f = 1.25 };

C++ にはこの機能がないため、最初に名前を付けたメンバーを初期化したい場合を除いて、ほとんど運がありません。

もちろん、割り当てを使用できます。

union { int i; float f; } obj;
obj.f = 1.25;

私が提案するのは、完全に良い回避策です。あなたがやりたいことができます; 必要な構文でそれを行うことはできません。

この場合、union型に名前を付けても、より広いスコープで表示できるようにし、型の値を返す関数を作成しない限り、特に役に立ちません。

union u { int i; float f; };
u init_f(float f) { u result; result.f = f; return result; }

// later

u obj = init_f(1.25);

アップデート :

上記を書いたとき、C++ に無名共用体が存在することを知りませんでした。C11 は、匿名の共用体と構造体を許可しますが、それを囲む共用体または構造体のメンバーとしてのみ許可します。C++11 では、標準の次の例のように、無名共用体オブジェクトを定義できます。

void f() {
  union { int a; const char* p; };
  a = 1;
  p = "Jennifer";
}

g++ 4.7.2 では、匿名共用体オブジェクトの初期化が許可されていないようです。たとえば、次のようになります。

int main() {
    union {
        int i;
        float f;
    } = { 42 };
}

次のエラーが発生しg++ -std=c++11ます。

c.cpp: In function ‘int main()’:
c.cpp:5:5: error: expected ‘;’ after union definition
c.cpp:5:7: error: expected primary-expression before ‘=’ token

C++11 標準のセクション 9.5 には、無名共用体の初期化子を禁止するものは見当たりません。これは、おそらく将来のリリースで修正される g++ の制限であると考えさせられます。

この制限が言語によるものか g++ によるものかにかかわらず、共用体に名前を付けることで回避できます。

union { int i; float f; } obj = { 42 };

(ただし、 and だけでなく and を参照する必要があります) 、obj.iまたは初期化子ではなく代入を使用して:obj.fif

union { int i; float f; };
i = 42;

(この制限が言語またはコンパイラによって課されているかどうかを解決したら、この回答をクリーンアップします。)

于 2013-06-28T17:56:13.857 に答える