3

を取得するために左側を評価するために (古いまたは新しい) のどの値を使用するかについて混乱があるため、ステートメントa[i]=i++;は未定義です。このコンパイラは、.. でコンパイルされた場合、このステートメントに対して警告を発します (操作は未定義の可能性があります) 。iL-value-Wall

以下のコードでは、ステートメントx->a = x->b, ++x++->b;
xが変更されており、左側ではL-value. このステートメントを で実行しても、コンパイラは警告を出しません-Wall

これが未定義の動作ではない理由を誰かが説明してもらえますか? ありがとう!

struct Data {
int a;
int b;
} y[4] = { 10, 20, 30, 40};

struct Data *x = y;
int i;

for(i=0; i<2; i++) {
    x->a = x->b, ++x++->b;
    printf("%d %d\t", y[i].a, y[i].b);
}
4

2 に答える 2

12

コンマ演算子の優先順位は最も低く、

式:
代入式
,代入式

それで

x->a = x->b, ++x++->b;

実際には

(x->a = x->b), ++(x++->b);

また、コンマ演算子はシーケンス ポイントであるため、2 つの変更xが連続し、未定義の動作はありません。

于 2013-06-18T15:41:37.050 に答える
7

x->a = x->b, ++x++->b;未定義の動作を呼び出しません。コンマ演算子は代入演算子よりも優先順位が低いため、このコードは次と同等です。

x->a = x->b;
++x++->b;

そこの 2 行目では、後置演算子が を++変更してxおり、前置演算子が参照解除された構造体++のメンバーを変更しています。bシーケンス ポイント規則に違反していません。

于 2013-06-18T15:41:17.593 に答える