2つのメカニズムは全く異なるメカニズムを使用していますが、そのうちの1つはC++ 11固有であり、もう1つはC99固有です。
最初のビット、
struct A get() {
return {0};
}
は[stmt.return]に依存する(6.6.3(2))で
(...)Aを言うC++ 11、 braced-init-listを持つreturn文は、指定された初期化子リストからcopy-list-initializationによって関数から返されるオブジェクトまたは参照を初期化します。 [例:
std::pair<std::string,int> f(const char *p, int x) {
return {p,x};
}
から端例]
この通路は、(C++ 11の前にもC++)Cには存在しないので、Cコンパイラは、それを扱うことができません。一方
、
struct A get() {
return (struct A){0};
}
は、いくつかのC++コンパイラ、特にGCCは、言語拡張としてそれを提供するが(C++に存在しない「化合物リテラル」と呼ばれるC99機能を使用して、GCCは約警告それは - ペディンと一緒に)。このセマンティクスは、C99標準のセクション6.5.2.5で詳細に説明されています。お金の引用は、初期化子の中括弧で囲まれたリストに続いて括弧で囲んタイプ名で構成されてい
4後置式はリテラル化合物です。それは初期化子リストによって値が与えられる無名のオブジェクトを提供します。 (脚注80)
80)これはキャスト式とは異なります。たとえば、キャストはスカラー型またはvoid
への変換のみを指定し、キャスト式の結果は左辺値ではありません。
この場合、(struct A){0}
は戻り値にコピーされ返される無名のオブジェクトです。 (現代のコンパイラはこのコピーを削除するので、ランタイムオーバーヘッドを恐れる必要はありません)。
そしてそこには、章と節があります。なぜこれらの機能がそれぞれの言語で行われているかが魅力的な議論になるかもしれませんが、それぞれの標準化委員会の外にいる誰もが質問に対する正式な回答をすることは難しいです。どちらの機能もCとC++の分割方法の後に導入されており、それらは並んで開発されていません(そうするのは意味がありません)。小さな事でも発散は避けられません。
私は、C++コンパイラが自動的に戻り値を 'struct A'に変換すると仮定します。そして、c = +では 'struct A get()'だけを 'A get()'する必要はありません。 –
'(*)'とは何ですか? – Ankur
C++コンパイラ*以前*をC++ 11で試しましたか? [それは確かにそれもpukes](http://ideone.com/PBFlOR)。 – WhozCraig