• ベストアンサー

C言語での式の評価順序について

ANSI C規格では 「式の評価順序は処理系により異なる」 とのことですが,次のプログラムがどのような評価順序で処理されたのか,どうしても分かりません. C言語の細かいところまでご存知の方がいらっしゃいましたら教えてください. #include <stdio.h> main(){ int c; c = 0; printf("%d\n", c + 1 == ++c); c = 0; printf("%d\n", c + 0 == ++c); } 私の処理系のccでコンパイルして実行すると 1 1 と出力されます. 上の二つの条件式が両方とも真であると解釈され得るような評価順序が存在するのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tullio
  • ベストアンサー率20% (11/53)
回答No.1

コンパイラは何回か作ったことがあります. OSF1の付属コンパイラ,IRIX6.5の付属コンパイラ,そして両方のgccで試してみました. OSF1では「どうなるか分からないから止めた方が良いよ」という警告が出て,結果は1,0でした. IRIXでは,今度は0,1でした. gccでは,1,1でした. で,gcc -Sでアセンブラコードを見てみたところ,gccでは上の式は変数cの値を保存しておいて,左辺と右辺の評価で同じコードで1を足していました. 下の式では,右辺を評価してcをインクリメントした後で左辺を評価する時にインクリメントされたcの値を読み出していました. でも,カーニハン&リッチーには,そういうプログラムは書いてはいけません,と書いてありますね ;-P

zabuzaburo
質問者

お礼

ありがとうございました.こういう問題で一日悩んでいると,カーニハン・リッチーの教えを痛感してしまいますね.gcc -Sを見て自分で解決できるように,アセンブラの勉強を始めようと思います.

その他の回答 (1)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

Windows系での結果です。 Microsoft Visual C++6.0(32bit)と1.51(16bit)で検証し両方で何の警告も無く「1を2つ」出力しました。 16bitコンパイラで生成されたコードは 上の式: mov WORD PTR -4[bp],OFFSET 0 ; c=0 mov ax,WORD PTR -4[bp] ; add ax,OFFSET 1 ; c+1→ax add WORD PTR -4[bp],OFFSET 1 mov cx,WORD PTR -4[bp] ; ++c→cx cmp ax,cx ; 比較 下の式: mov WORD PTR -4[bp],OFFSET 0 ; c=0 add WORD PTR -4[bp],OFFSET 1 ; ++c mov ax,WORD PTR -4[bp] ; c→ax cmp WORD PTR -4[bp],ax ; 比較 上の式と下の式では評価順が違うようです。

zabuzaburo
質問者

お礼

ご親切にありがとうございます.アセンブラは初心者なのですが右につけてくださった注釈のおかげで理解できました.今度は評価順がなぜ変わるのか研究しようと思ってます.