【C言語】clang と VS と Eclipse と私(まだまだ続く 関数の評価順序)
C言語の関数の評価順序について。
こちらの記事の続きです。
しつこいわ、私って(笑)。
前記事で次のように申しました。
VS、gcc は本当に第3引数から評価しているのか
そして。
(1)引数の並びを逆にするとどうなるのか
(2)引数で関数を呼び出すとどうなるのか
この(1)(2)を試してみました。
(1)引数の並びを逆にするとどうなるのか
ソースコード
oe1、oe2、oe3、oe4 の各関数について少し解説します。
oe は 「Order Evaluation(評価の順序)」の略称です。
1~4 の4種類を用意しました。
それぞれ次のように引数を変えています。
一番のポイントはマクロ「MAX」の位置。
第1引数に置くのか、第3引数に置くのか。
引数を第1引数から評価するのか、第3引数から評価するのかを知ることが目的です。
oe3、oe4 は、更に i と j を単体で演算しました。
これによって評価の順序が変われば、演算結果が変わります。
以下がそのソースコードです。
#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
void oe1(void)
{
int i = 3;
int j = 5;
printf("MAX処理中 i = %d, j = %d, max = %d\n", i, j, MAX(++i,j--));
}
void oe2(void)
{
int i = 3;
int j = 5;
printf("MAX処理中 max = %d, i = %d, j = %d\n", MAX(++i, j--), i, j);
}
void oe3(void)
{
int i = 3;
int j = 5;
printf("MAX処理中 i = %d, j = %d, max = %d\n", i*=2, j--, MAX(++i,j--));
}
void oe4(void)
{
int i = 3;
int j = 5;
printf("MAX処理中 max = %d, i = %d, j = %d\n", MAX(++i, j--), i*=2, j--);
}
int main()
{
oe1();
oe2();
oe3();
oe4();
return 0;
}
結果
さて。
結果はどうなるでしょうか。
clang
MAX処理中 i = 3, j = 5, max = 4
MAX処理中 max = 4, i = 4, j = 3
MAX処理中 i = 6, j = 5, max = 8
MAX処理中 max = 4, i = 8, j = 3
VS2019
MAX処理中 i = 4, j = 3, max = 4
MAX処理中 max = 4, i = 4, j = 3
MAX処理中 i = 8, j = 3, max = 4
MAX処理中 max = 4, i = 8, j = 3
Eclipse
MAX処理中 i = 4, j = 3, max = 4
MAX処理中 max = 4, i = 4, j = 3
MAX処理中 i = 8, j = 3, max = 4
MAX処理中 max = 8, i = 8, j = 5
ん。
ん、ん、ん?
oe3 と oe4。
すごいことになってる。
まさかまさかの結果。
全体を見ると三者三様の有り様。
アセンブラはあるけど。
あー。
またほじくり返す?😅
(2)引数で関数を呼び出すとどうなるのか
ソースコード
評価順序を知る最も単純にしてわかりやすい方法は、関数を呼び出してみることです。呼び出された関数で標準出力に出力すれば一目瞭然。
ではやってみます。
ソースコードはこちら。
#include <stdio.h>
int func1(void)
{
printf("func1\n");
return 1;
}
int func2(void)
{
printf("func2\n");
return 2;
}
int func3(void)
{
printf("func3\n");
return 3;
}
int main()
{
printf("func1 = %d, func2 = %d, func3 = %d\n", func1(), func2(), func3());
return 0;
}
結果
上のソースコードを clang、VS、Eclipse のそれぞれの環境でコンパイルし実行してみます。
結果は次の通り。
clang
func1
func2
func3
func1 = 1, func2 = 2, func3 = 3
VS2019
func3
func2
func1
func1 = 1, func2 = 2, func3 = 3
Eclipse
func3
func2
func1
func1 = 1, func2 = 2, func3 = 3
VS2019 と Eclipse は右からなのかぁ。
後書き
さて。
例の (1) の結果。
どうなってるんでしょうねぇ。
アセンブラを解析するかなぁ。