このように構成された3つの関数(foo、bar、baz)がある場合...
foo(bar(), baz())
C ++標準によって、barがbazの前に評価されるという保証はありますか?
回答:
いいえ、そのような保証はありません。C ++標準によれば、仕様は規定されていません。
Bjarne Stroustrupは、「C ++プログラミング言語」の第3版のセクション6.2.2でも、それをいくつかの理由で明示的に述べています。
式の評価順序に制限がない場合、より良いコードを生成できます
技術的にはこれは同じセクションの前の部分を指しますが、式の部分の評価の順序も指定されていません。
int x = f(2) + g(3); // unspecified whether f() or g() is called first
bar()とbaz()の順序は指定されていません-標準が言う唯一のことは、両方がfoo()が呼び出される前に評価されるということです。C ++標準のセクション5.2.2 / 8から:
引数の評価順序は不定です。
bar
、次に1行目baz
、次に2行目bar
などを実行できない)とも述べており、これも便利です。:-)
[5.2.2]関数呼び出しから、
引数の評価順序は不定です。引数式評価のすべての副作用は、関数に入る前に有効になります。
そのため、保証はありませんbar()
前に実行されるbaz()
のみであること、bar()
そしてbaz()
前に呼び出されますfoo
。
[5]式から、次の点にも注意してください。
特に明記されていない限り(たとえば、
&&
およびの特別なルール||
)、個々の演算子のオペランドと個々の式の部分式の評価の順序、および副作用が発生する順序は、規定されていません。
そのため、でbar()
以前baz()
に実行するかどうかを尋ねていたとしてもfoo(bar() + baz())
、順序はまだ指定されていません。
&
、&&
左から右への評価が保証されfalse
ます。最初のオペランドがの場合、2番目のオペランドは評価されません。」
C ++ 17は、C ++ 17まで指定されていなかった演算子の評価順序を指定します。C ++ 17によって導入された評価順序保証は何ですか?の質問を参照してください。しかし、あなたの表現に注意してください
foo(bar(), baz())
まだ指定されていない評価順序があります。
C ++ 11では、関連するテキストは8.3.6デフォルトの引数/ 9(Emphasis mine)にあります。
デフォルトの引数は、関数が呼び出されるたびに評価されます。関数の引数の評価順序は不定です。したがって、関数のパラメーターは、評価されない場合でも、デフォルトの引数で使用されません。
同じ言い回しがC ++ 14標準でも使用されており、同じセクションにあります。
他の人がすでに指摘したように、この規格では、この特定のシナリオの評価順序に関するガイダンスは提供されていません。この評価の順序はコンパイラーに委ねられ、コンパイラーが保証する場合があります。
C ++標準は、実際にはコンパイラにアセンブリ/マシンコードの構築を指示する言語であることを覚えておくことが重要です。標準は方程式の一部にすぎません。標準があいまいであるか、実装が明確に定義されている場合は、コンパイラーを使用して、C ++命令を真の機械語に変換する方法を理解する必要があります。
したがって、評価の順序が要件であるか、少なくとも重要であり、クロスコンパイラー互換であることは要件ではない場合、コンパイラーが最終的にこれをどのように組み合わせるかを調査すると、答えは最終的にそこにあります。コンパイラは将来的にその方法を変更する可能性があることに注意してください