「cout << a << a」の謎: 未定義の動作を明らかにする
最近、インタビューでの不可解な質問がきっかけとなった議論: 次の正しい出力は何ですか?
int a = 0; cout << a++ << a;
一部の候補者は自信を持って「01」を選択しましたが、他の候補者はその動作が定義されていないと理由付けしました。最初は一部の人を驚かせた答えです。
問題の核心は評価にあります。ステートメントの順序と副作用。これを理解するために、関数呼び出しに相当するものに拡張してみましょう。
std::operator<<(std::operator<<(std::cout, a++), a);
C は、先行する評価の副作用がシーケンス ポイントで実行されることを保証します。ただし、引数の評価間にシーケンス ポイントがないため、引数の評価順序は不確実なままになります。a を a の前に評価することも、その逆も可能です。
この評価順序の曖昧さにより、ステートメントの動作が未定義になります。ただし、a と a の場合、前者の結果が後者の引数として使用され、出力は評価の順序に依存します。
C 17 更新: 明瞭さの真っ只中曖昧さ
C 17 では、ルールが進化しました。シフト演算子に関する特定のステートメントが導入され、左側のオペランドの評価と副作用が右側のオペランドの評価と副作用より前に発生する必要があると規定されました。
In a shift operator expression E1<>E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2. この義務により、式「a」
このセマンティクスの改良により、C 17 では出力 "01" が生成されます。 C の慣用的な慣例に合わせて、シフト演算子を含む式の評価に一貫性を持たせます。
以上が「cout」の出力は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。