Order of evaluation
C 演算子のオペランドの評価順序、関数呼び出し式における関数引数の評価順序、および任意の式内の部分式の評価順序は未規定です(以下で明記される場合を除く)。コンパイラはこれらを任意の順序で評価し、同じ式が再度評価される際には異なる順序を選択する可能性があります。
C言語には左から右、あるいは右から左への評価順序という概念は存在しません。これは演算子の左結合性や右結合性とは混同しないでください:式 f1 ( ) + f2 ( ) + f3 ( ) は ( f1 ( ) + f2 ( ) ) + f3 ( ) と解析されます。これは operator + の左結合性によるものですが、実行時には関数呼び出し f3 ( ) が最初に評価されることも、最後に評価されることも、 f1 ( ) と f2 ( ) の間に評価されることもあります。
目次 |
定義
評価
コンパイラは各式または部分式に対して2種類の評価を実行します(いずれもオプションです):
- value computation(値計算) : 式によって返される値の計算。これにはオブジェクトの同一性の決定( lvalue evaluation )またはオブジェクトに以前代入された値の読み取り(rvalue evaluation)が含まれる場合があります。
-
side effect(副作用)
:
volatilelvalueで指定されたオブジェクトへのアクセス(読み取りまたは書き込み)、オブジェクトの変更(書き込み) 、アトミック同期 (C11以降) 、ファイルの変更、浮動小数点環境の変更(サポートされている場合)、またはこれらの操作のいずれかを行う関数の呼び出し。
式が副作用を生じず、かつコンパイラが値が使用されないと判断できる場合、その式は 評価されない可能性があります 。
順序付け
Sequenced-before は、同一スレッド内の評価間における非対称的、推移的、ペアワイズの関係です(アトミック型とメモリバリアが関与する場合はスレッドをまたがる可能性があります)。
- もし シーケンスポイント が部分式 E1 と E2 の間に存在する場合、 E1 の値計算と副作用の両方は、 E2 のあらゆる値計算と副作用に対して 先行シーケンス されます。
|
(C11以降) |
ルール
&&
(論理AND)、
||
(論理OR)、および
,
(コンマ演算子)。
?:
の最初(左)のオペランドの評価後、および2番目または3番目のオペランド(評価される方)の評価前にシーケンスポイントが存在します
|
5)
完全宣言子の終端にはシーケンスポイントが存在する。
6)
ライブラリ関数の戻り直前にはシーケンスポイントが存在する。
|
(C99以降) |
|
9)
任意の演算子のオペランドの値計算(副作用は除く)は、演算子の結果の値計算(副作用は除く)よりも前にシーケンスされる。
10)
直接代入演算子およびすべての複合代入演算子の副作用(左引数の変更)は、左右両方の引数の値計算(副作用は除く)よりも後にシーケンスされる。
11)
後置インクリメントおよび後置デクリメント演算子の値計算は、その副作用よりも前にシーケンスされる。
12)
他の関数呼び出しよりも前にシーケンスされず、後にシーケンスされない関数呼び出しは不定シーケンスされる(異なる関数呼び出しを構成するCPU命令は、関数がインライン化されていてもインターリーブされない)
13)
初期化
リスト式では、すべての評価は不定シーケンスされる
14)
不定シーケンスされた関数呼び出しに関して、複合代入演算子の操作、および前置形式と後置形式のインクリメント・デクリメント演算子は単一の評価である。
|
(C11以降) |
未定義動作
i = ++i + i++; // undefined behavior i = i++ + 1; // undefined behavior f(++i, ++i); // undefined behavior f(i = -1, i = -1); // undefined behavior
f(i, i++); // undefined behavior a[i] = i++; // undefined behavior
関連項目
演算子の優先順位 は、式がソースコード表現からどのように構築されるかを定義します。
|
C++ ドキュメント
for
評価順序
|