は有効な初期化子ですが、式ではないため失敗します{3, 4}
(少なくとも C ではありません。C++ の詳細については以下を参照してください)。
C のすべての式には、式自体を調べることで判別できる型があります。、 or (配列型)、または無数の他の型のいずれかである{3, 4}
可能性があります。struct T
int[2]
C99 では、複合リテラルと呼ばれる新しい機能が追加されました。これは、初期化子と同様の構文を使用しますが、式を作成して型を指定できます。
b = (struct T){3, 4};
はキャスト演算子で(struct T)
はないことに注意してください。これは、複合リテラルの構文の一部です。
複合リテラルの詳細については、ドラフト C11 標準のセクション 6.5.2.5 を参照してください。
複合リテラルは、1999 年の ISO C 標準 (C99) で導入されました。コンパイラが C99 以上をサポートしていない場合 (*咳*マイクロソフト*咳*)、それらを使用することはできません。
C++ (別の言語であることを忘れないでください) を使用している場合、複合リテラルはサポートされていませんが、別の方法がある可能性があります。Potatoswatter がコメントで指摘しているように、これは次のとおりです。
b = T{3, 4};
は C++11 で有効です (ただし、以前のバージョンの C++ 言語では有効ではありません)。これは、C++ 標準のセクション 5.2.3 [expr.type.conf] で説明されています。
さらに言えば、これは:
b = {3, 4};
も有効な C++11 構文です。この形式は、割り当ての右側を含む、指定された多くのコンテキストで使用できます。これは、C++ 標準のセクション 8.5.4 [dcl.init.list] で説明されています。
C++ 標準の最近のドラフトの 1 つが N3485 です。
(g++ は、拡張機能として C++ の C99 スタイルの複合リテラルをサポートします。)
また、C99 より前のコンパイラに行き詰まっている場合は、次のような独自の初期化関数をいつでも作成できます。
struct T init_T(int x, int y) {
struct T result;
result.x = x;
result.y = y;
return result;
}
/* ... */
struct T obj;
/* ... */
obj = init_T(3, 4);
これは煩わしい余分な作業です (C99 が複合リテラルを追加したのはそのためです) が、これで十分です。一方、ほとんどの場合、おそらく初期化を使用する方がよいでしょう:
struct T obj;
/* ... */
{
struct T tmp = { 3, 4 };
obj = tmp;
}
どちらが優れているかは、おそらくプログラムの構造によって異なります。