読者です 読者をやめる 読者になる 読者になる

C言語の関数の引数の評価順序

あらすじ

( ^o^)<ショートコーディング楽しい!
( ^o^)<よーしprintfの引数の中でポインタの参照とインクリメント同時にやっちゃおう!
(;^o^)<あれ…期待した通りに動作しないぞ…
( ˘⊖˘) 。o(待てよ、引数の評価順序ってどうなってるんだ)
|C/C++|┗(☋` )┓三
( ◠‿◠ )☛未定義だ
▂▅▇█▓▒░('ω')░▒▓█▇▅▂うわあああああああああああ


C言語の関数の引数の評価順序に見事に引っかかった。
C言語では関数の引数の評価順序は未定義で処理系によって異なるらしい。
そこで、ちょっと気になったので手元で使えるGCCとVisualStudioで検証してみることにした。

検証コード

#include <stdio.h>
int a;
int func(int arg){
  a=arg;
  return arg;
}
int main(void){
  printf("%d %d\n",func(1),func(2));
  printf("a:%d",a);
  return 0;
}

関数funcに渡された引数を変数aに入れてから引数をそのまま返します。
その後2行目に変数aを出力します。
出力された変数aが1だったら右→左の順、2だったら左→右の順になります。

実行結果

GCC6.1.1場合

1 2
a:1

VisualStudio2015場合

1 2
a:1

どちらともaの値は1になっており引数の評価は右→左の順で行われている様です。

まとめのようなもの

結果はどちらとも右から左だったので普通は右から左に評価されてくのでしょうか。
どちらにしろ未定義とのことなので使わないほうがいいんですが、知っておくと何か役に立つのかもしれないですね。
あとは左から右に評価されてく処理系とかあったりするのか気になります。
その辺も含めて又の機会にもうちょっと詳しいところを調べてみたいと思いました。


参考
引数として関数を渡したときの実行順序 - mooz deceives you
BohYoh.com-C/C++ FAQ 関数に渡される実引数の評価順序はどうなっていますか。
javaの場合は左から右に統一されているんですね。
引数の評価順序 - Togetterまとめ
↑(x=3)+(x+4)の様な部分式の場合も同じようなことになるみたいです。

P.S.
今日外を歩いてたら鳥の糞が直撃しました
すごくつらいです