C言語での引数の評価順序について
ゲスト
ゲスト
ATOMRSS
  • コード求むID: 342
  • 登録日時:  2008/11/06 19:30
  • 最終更新日時: 2008/11/19 18:35
  • アクセス数: 441
  • タグ:  c/c++
  • codeなにがしブックマークに追加する 0 users
  • このページを del.icio.us に追加
  • このページをはてなブックマークに追加

#include <stdio.h>
void f(int x;int y;int z){
	printf(“%d %d %d\n”,x,y,z);
}
int main(){
	int n=10;
	f(n++, --n, ++n);
	return 0;
}
上のようなプログラムを書きCentOSのgccでコンパイルしたところ
10 11 11
と表示されました。

予想では
10 10 11
と表示されると思ったのですが、なぜ10 11 11と表示されたのかわかるかたおられませんか?

コメント

  • ゲスト
  • 1:ゲスト (み)
  • 2008/11/06 21:09

こういうのは、評価順序の不定とか未定義とか言われる奴で、基本的にやってはいけないこととされていると思います。
http://www.st.rim.or.jp/~phinloda/cqa/cqa7.html
ここにいろいろ解説されてました。
コンパイラの実装しだいでどうなるかはわからないということなので、やめたほうがよい書き方ですね。

GJGJ

  • ゲスト
  • 2:ゲスト (abc)
  • 2008/11/06 22:30

たぶん、f(a, b, c)は初めにc->b->aの順番に評価され、a->b->cの順番で値がf()のスタックにつまれるので、出力のようになるんだと思います。

評価と値というのは、
n=10; ++n;の ++n は 評価で11、値(n)が11になる。
n=10; n++;の n++ は 評価で10、値(n)が11になる。
ということです。

しかし、すでに述べられているように、コンパイラによって評価順序が異なるので、必ずしもこうはなりません。

GJ

  • otn
  • 4:otn
  • 2008/11/19 18:35

おもしろいですね。
後ろから順に評価してその都度スタックに積むと思っていましたが、
計算をまず後ろから順に3つ全部した上で、後ろから順に積んでいるようです。
第一引数は n++ なので第三、第二の評価でプラマイゼロの状態でインクリメント前の値を別途保管するので、10になりますが、
第二引数、第三引数は、すべての計算が終わった後は11なのでその値が積まれます。

都度積むコンパイラもあると思うので、その場合は10,10,11になりますね。
実際、Windowsの「Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland」だと、
10,10,11 になります。

あと、gcc でもvolatile int n=10; にすると10,10,11に。

  • GoodJob
  • 0

前へ 1 次へ

コメントする

[block]から[/block]までの範囲はブロック表示されます。
部分的に目立たせたい時や、引用などにお使いください。

[code]から[/code]までの範囲は等幅表示されます。
ソースコードや設定ファイルの記述などにお使いください。

ゲスト投稿者:ゲスト:

関連ソースコード・ノウハウを登録

PDFLib | A library for processing PDF on the fly プレゼン公開・共有サイト handsOut.jp オープンタイプ株式会社 チーム・マイナス6% - みんなで止めよう温暖化

ブックマークコメント