5

次のコードについて考えてみます。

int i, k, m;
k = 12;
m = 34;
for (i = 0; i < 2; i++) ((i & 1) ? k : m) = 99 - i;
printf("k: %ld   m: %ld\n\n", k, m);

このばかげた例では、条件演算子式は次のショートカットです。

if (i & 1) k = 99 - i; else m = 99 - i;

私のコンパイラは文句を言わず、このコードを実行すると期待される出力が得られます

k: 98   m: 99

しかし、私の質問は、これがC標準に準拠した有効なコードであるかどうかです。私はそれが以前に使用されたようなものを見たことがありません。

4

3 に答える 3

8

C11標準の脚注110:

条件式は左辺値を生成しません。

そして6.5.16段落2:

代入演算子は、左側のオペランドとして変更可能な左辺値を持つ必要があります。

いいえ、そのコードはC標準に準拠していません。

C ++ 11では、次のよう有効です。

2番目と3番目のオペランドが左辺値で同じタイプの場合、結果はそのタイプで左辺値になります。

つまり、これはCとC++が大きく異なるほこりっぽいコーナーの1つです。コンパイラでエラーが発生しない場合は、適切なCコンパイラではなく、「Cモード」のC++コンパイラを使用していると思います。MSVC?

于 2012-04-05T15:27:34.787 に答える
4

これは正当なCではなく、それを受け入れるコンパイラは間違っています。ただし、次の方法でも同じことができます。

*((i & 1) ? &k : &m) = 99 - i;

そしてそれは合法的なCになります。

于 2012-04-05T16:23:17.850 に答える
1

C ++ではlvalとして条件付きを使用することは有効ですが、Cでは使用できません。

C ++の場合(ISO?IEC 14882:1998(E)5.16.4)

2番目と3番目のオペランドが左辺値で同じタイプの場合、結果はそのタイプで左辺値になります。

Cで同様のトリックを使用したい場合は、ポインターを使用する必要があります。

ISO / IEC 9899:TC2、6.5.14.6

2番目と3番目のオペランドの両方がポインターであるか、一方がnullポインター定数で、もう一方がポインターである場合、結果の型は、両方のオペランドが指す型のすべての型修飾子で修飾された型へのポインターになります。

*((i & 1) ? &k : &m) = 99 - i;
于 2012-04-05T15:25:11.257 に答える