2

私は、式がどのように評価されているかを一度だけ心に留めようとしています。そして、私のこの探求で、私は何を作るべきかわからないこの例を思いつきました.

#include <iostream>
using namespace std;
typedef void(*func)(int);

void r( int i )
{
    cout << i << endl;
}
func f( int i )
{
   cout << i << endl;
   return &r;
}

int main()
{
   int i = 0;
   f(++i)(++i);
   return 0;
}

このコードを MVSC 2008 でコンパイルすると、次の出力が生成されます: 2 2. 同じコードを gcc 4.8.1 でコンパイルすると、警告が発生し (i に対する操作は未定義の可能性があります)、次の出力が生成されます: 1 2.

私が理解しようとしているのは、gcc 4.8.1 が未定義の動作の場合があると考える理由です。両方のプレインクリメントの副作用は、相互に関連して順序付けられます。

乾杯、アンドレイ

4

2 に答える 2

7

両方のプレインクリメントの副作用は、相互に関連して順序付けられます。

いいえ、そうではないです。各引数の評価は、その関数呼び出しの前に順序付けられ、関数呼び出しは互いに順序付けられます。ただし、両方とも最初の呼び出しの前に評価できます。その場合、それらを互いに順序付けするものは何もありません。

于 2013-10-24T13:24:19.767 に答える
2

「プレインクリメント」の意味によって異なります...次のように読んでいます:

  ++i
f(i)
      ++i
f (i) (i)

しかし、次のように簡単に行うことができます。

 ++i
      ++i
 f(i)
 f(i) (i)

仕様がどちらか一方を要求するとは思わない。

于 2013-10-24T13:25:40.940 に答える