2015-12-30 3 views
5

この行はC私はC++を使用するときにコンパイルではなく:がコンパイル

gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL))); //make an lvalue with alloca

私はこの違いによって驚いて。 C++の警告さえありません。

私はgcc -x cを指定すると、メッセージは次のとおりです。

playground.cpp:25:8: error: lvalue required as unary '&' operand 
gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL))); 
     ^

はちょうどアドレス演算子ここ&はありませんか? CとC++の違いは何ですか?

Cでコンパウンドリテラルを使用することはできますが、C & C++で動作するように構文を変更することは可能ですか?

+2

また、違いは '&'についてではなく、 '(* time_t *)alloca(sizeof(time_t))= time )) 'は左辺値かどうかです。 – immibis

+1

また、これを2行に書くのはなぜですか? 'time_t t = time(NULL); gmtime(&t); ' – immibis

+0

@immibis主に一時オブジェクトのアドレスを取得したいので(' time_t'の値は一度だけ使用されます)、Cで複合リテラルが見つかりましたので便利ですが、C++では使用できません。 – cshu

答えて

8
C11で

6.5.16/3:C++ 14 5.17/1で

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

(各場合において言語標準の以前のバージョンは同じものを指定しました) 。

アドレス演算子のみが左辺値で動作することができるので、コードは「問題に関してはC++ではなくCの


で正しいそれはそれを動作させるために私の構文を変更することは可能です両方ともC & C++?これは望ましい目標ではありません。 2つの言語が異なり、あなたが書いているものを決定する必要があります。これは、CとJavaの両方で動作する構文に固執しようとするほど意味があります。

他の人が示唆したように、あなたが書くことができる:ビーイングのあなたの元のコードの上に利点がある

time_t t = time(NULL); 
gmtime(&t); 

  • 単純に、したがって、容易に
  • を理解し、維持するためにはありません非標準に依存alloca機能
  • は、アライメント違反の可能性がありません
  • はこれ以上メモリを使用せず、おそらくlessを使用します
+0

ルールの背後にある論理的根拠は分かっていませんが、元々はC言語ではありませんでした(割当ての結果を試して修正することはほとんどありません)が、C++が開発されたときには、 'operator = 'を多重定義し、自己(左辺値)への参照を返すオブジェクトとの一貫性のために左辺値にしてください。 –

+0

いい仕事です。右辺値と左辺値に関する別の規則と関係していることは分かっていましたが、 '= '演算子ではなく'& '演算子を調べていました。 +1。 – ApproachingDarknessFish

関連する問題