8

演算子の優先順位が尊重されていないように見える、奇妙なVS2008C++の問題で立ち往生しています。

私の質問は、これの出力は何ですか?

int i = 0;  
std::cout << ((i != 0) ? "Not zero " : "zero ") << ++i << std::endl;  

通常、++は優先され<<ますよね?または<<、?よりも高い優先順位を与える関数呼び出しのように見なされ++ますか?これに対する100%正しい標準的な答えは何ですか?

確認するために、新しい空のプロジェクト(VS2008コンソールアプリ)を作成し、このコードのみをメインに貼り付けました。結果は次のとおりです。

Debug|Win32: “zero 1”  
Release|Win32: “zero 1”  
Debug|x64: “zero 1”  
Release|x64: “Not zero 1”

ところで、次の例ではまったく同じ結果が得られます。

i = 0;  
printf("%s %d\n", ((i != 0) ? "Not zero" : "zero"), ++i);  

また、リリースで最適化のタイプを変更しても効果はありませんが、最適化を無効にすると、他の構成と同様に「ゼロ1」が出力されます。

4

1 に答える 1

16

これは、演算子の優先順位とは関係ありません。
関数呼び出しのシンタックス シュガーである << を使用しています。

std::cout << ((i != 0) ? "Not zero " : "zero ") << ++i << std::endl; 

// Equivalent too:

operator<<(operator<<(operator<<(std::cout, ((i != 0) ? "Not zero " : "zero ")), ++i), std::endl);

ここでの唯一の規則は、関数が呼び出される前にパラメーターが完全に評価されなければならないということです。パラメーターが評価される順序に制限はなく、それらの評価が呼び出しとインターリーブされる (または部分的に評価される) 場合でも、制限はありません。

解釈 1:

1) ((i != 0) ? "Not zero " : "zero "))
2) ++i
3) operator<<(std::cout, (1));
4) operator<<((3), (2));
5) operator<<((4), std::endl);

解釈 2:

1) ++i
2) ((i != 0) ? "Not zero " : "zero "))
3) operator<<(std::cout, (2));
4) operator<<((3), (1));
5) operator<<((4), std::endl);

解釈 3:

1) ((i != 0) ? "Not zero " : "zero "))
2) operator<<(std::cout, (1));
3) ++i
4) operator<<((2), (3));
5) operator<<((4), std::endl);

解釈 1 を参照してみる:
適用しなければならない規則:

 A) (1) happens before (3)
 B) (2) happens before (4)
 C) (3) happens before (4)
 D) (4) happens before (5)
于 2010-08-11T22:29:11.507 に答える