web-dev-qa-db-ja.com

C ++関数パラメーターでの評価の順序

このように構成された3つの関数(foo、bar、baz)がある場合...

foo(bar(), baz())

C++標準によって、barがbazの前に評価されるという保証はありますか?

84
Clark Gaebel

いいえ、そのような保証はありません。 C++標準によれば、仕様は規定されていません。

Bjarne Stroustrupはまた、「C++プログラミング言語」の第3版のセクション6.2.2で、それをいくつかの理由で明示的に述べています。

式の評価順序に制限がない場合、より良いコードを生成できます

技術的にはこれは同じセクションの以前の部分を指しますが、式の部分の評価の順序も指定されていません。

int x = f(2) + g(3);   // unspecified whether f() or g() is called first
94
Eli Bendersky

Bar()とbaz()に指定された順序はありません-標準が言う唯一のことは、両方がfoo()が呼び出される前に評価されるということです。 C++標準のセクション5.2.2/8から:

引数の評価順序は不定です。

20
anon

[5.2.2]関数呼び出しから、

引数の評価順序は不定です。引数式評価のすべての副作用は、関数に入る前に有効になります。

したがって、bar()baz()の前に実行される保証はなく、bar()およびbaz()foo

[5]式から、次の点にも注意してください。

特に明記されていない限り[例: _&&_と_||_]の特別なルール、個々の演算子のオペランドと個々の式のサブ式の評価の順序、および副作用が発生する順序は指定されていません。

そのため、bar()baz()の前にfoo(bar() + baz())を実行するかどうかを尋ねた場合でも、順序は未指定です。

18
Daniel Trebbien

C++ 17は、C++ 17まで指定されていなかった演算子の評価順序を指定します。質問を参照してください C++ 17によって導入された評価順序の保証は何ですか? しかし、式に注意してください

foo(bar(), baz())

まだ指定されていない評価順序があります。

10
S.M.

C++ 11では、関連テキストは 8.3.6 Default arguments/9 (Emphasis mine)にあります。

デフォルトの引数は、関数が呼び出されるたびに評価されます。 関数の引数の評価の順序は指定されていません。したがって、関数のパラメーターは、評価されない場合でも、デフォルト引数で使用されません。

同じ言い回しがC++ 14標準でも使用されており、 同じセクション の下にあります。

2
R Sahu

他の人がすでに指摘したように、この規格では、この特定のシナリオの評価順序に関するガイダンスは提供されていません。この評価の順序はコンパイラーに任され、コンパイラーが保証する場合があります。

C++標準は、実際にはアセンブリ/マシンコードの構築についてコンパイラに指示する言語であることを覚えておくことが重要です。標準は方程式の一部にすぎません。標準が曖昧な場合、または具体的に実装が定義されている場合は、コンパイラーを使用して、C++命令を真の機械語に変換する方法を理解する必要があります。

したがって、評価の順序が要件であるか、または少なくとも重要であり、クロスコンパイラ互換であることは要件ではない場合、コンパイラが最終的にこれをどのように組み合わせるかを調査します。答えは最終的にそこにあります。コンパイラは将来的にその方法を変更する可能性があることに注意してください

1