2

重複の可能性:
未定義の動作とシーケンスポイント

私はマイクロソフトビジュアルC++を使用しています。次の例を見てください。

int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n--);
printf(str);
// output is "hell world"

そのため、予期せず、私のコンパイラは、最初にnをデクリメントし、次にmemcpyを実行するコードを生成します。次のソースは、私が期待したことを実行します。

int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n);
n--;
printf(str);
// output is "helloworld"

最初に私はそれを自分自身に説明しようとしました。最後のパラメーターが最初にスタックにプッシュされるため、最初に評価される場合があります。しかし、私は、ポストインクリメント/デクリメント保証が次のセミコロンの後に評価されることを本当に信じています。

そこで、次のテストを実行しました。

void foo(int first, int second) {
    printf("first: %i / second: %i", first, second);
}
int n = 10;
foo(n, n--);

これにより、「first:10 / second:10」が出力されます。

だから私の質問は:この状況に定義された動作はありますか?誰かがこれが説明されている文書を私に指摘できますか?コンパイラのバグ~~OO~~を見つけましたか?

この例は、もう意味をなさないように単純化されています。これは、私の問題を示しているだけで、それ自体で機能します。

4

1 に答える 1

7

2つの関連する問題があります。まず、関数の引数の実行順序は指定されていません。保証されるのは、関数の本体に入る前にすべてが実行されることです。次に、これらの式の間にシーケンスポイントがない状態で変更および読み取りを行っているため、これは未定義の動作です。n

于 2013-02-04T21:11:57.987 に答える