4

C のシーケンス ポイントについての理解を深めようとしています。何かを確認したかっただけです。g現在、(1) は未定義であるのに対し、(2) は単に指定されていないと考えています。(2) では、 andの引数を評価した後にシーケンス ポイントが存在することに基づいています (したがって、シーケンス ポイント間で 2 回h変更することはありません)。iですが、 の引数の評価順序fはまだ指定されていません。私の理解は正しいですか?

#include <stdio.h>

int g(int i) {
    return i;
}

int h(int i) {
    return i;
}

void f(int x, int y) {
    printf("%i", x + y);
}

int main() {
    int i = 23;
    f(++i, ++i); // (1)
    f(g(++i), h(++i)); // (2)
    return 0;
}

編集:

ここでの重要なポイントは、コンパイラがどちらかの前に両方のインクリメントを自由に実行できるかどうか、gまたはh呼び出されるかどうかです.

4

2 に答える 2

12

Incorrect. Sequence points specify a partial order on the allowed ordering of operations. In case (2), there are sequence points:

  1. At the semicolon at the end of the line (1)
  2. After the evaluation of the arguments of g (i.e. the ++i) but before the call to g
  3. After the evaluation of the arguments of h (i.e. the ++i) but before the call to h
  4. After the evaluation of the arguments of f (i.e. after f and g have returned) but before the call to f
  5. After the return from f

So the partial order looks like this, from top to bottom:

    1
   / \
  /   \
 2     3
  \   /
   \ /
    4
    |
    | 
    5

2 and 3 are not ordered with respect to each other, since the order of evaluation of arguments is unspecified. Since i gets modified twice between the sequence points 1 and 4, the behavior is undefined.

于 2012-06-12T15:38:27.020 に答える
2

いいえ、6.5.2.2 10 によると、実際の呼び出しの直前に、部分式の引数の評価の間にシーケンス ポイントはありません。

それを見る 1 つの方法は、動作が未定義かどうかが指定されていないということです。実装がorの++i呼び出しの前に 2 つの部分式を順序付けする場合、動作は未定義ですが、部分式ができるだけ遅く ( and を呼び出す直前に) 評価される場合、動作は未規定です。ただし、実装は常に許可された未指定の動作から選択する自由があるため、全体的な結果は未定義です。gh++igh

于 2012-06-12T15:33:29.063 に答える