2012-04-05 12 views
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の標準に基づいて有効なコードですか?以前使ったようなものは見たことがありません。

+0

法的になります。しかし、あなたがそのようなコードを維持したいのであれば、特にそれが数年間触れられておらず、道路の5年後に戻ったときに何をするのか困惑させなければならないか、自分自身に尋ねるべきです。 –

答えて

8

脚注110:

条件式は、左辺値が得られません。

そして、6.5.16項2:

代入演算子は、その左のオペランドとして変更可能な左辺値を持たなければなりません。

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

、それが有効ある:

第二及び第三のオペランドが左辺値であり、同じタイプを持っている場合、結果はそのタイプであり、左辺値です。

これは、CとC++が大きく異なるこれらの埃の多いコーナーの別の1つです。あなたのコンパイラがエラーを生成しない場合、私はあなたが適切なCコンパイラではなく "Cモード"でC++コンパイラを使用していると推測しています。 MSVC?

+1

私はそれがC + +でも有効だと思います。 – hugomg

+0

私はMSVC++ 6.0で "Cモード"ではなく、C++コードとしてコンパイルしていました。私はCモードでコンパイルしようとしていません。たとえそれがCでもC++であっても、私はそれを使うつもりはありません。それは私が思いついたものでしたが、私がプログラムにしたいものをコード化する方法を考えていて、その妥当性が不思議になりました。お返事をありがとうございます! – zarulad

+0

@ザフラード:喜んで助けてください! –

1

(ISO IEC 14882?:1998(E)5.16.4)C++でのLVALとして条件を使用することが有効ですが、ないC.

でC++で

秒の場合第3オペランドは左辺値であり、同じ型を持ち、その結果は左辺値です。

あなたがCに似たトリックを使用したい場合は、ポインタを使用する必要がありますが:

ISO/IEC 9899:TC2、6.5.14.6

2番目と3番目のオペランドの両方がされている場合ポインタが1つはヌルポインタ定数で、もう1つはポインタです。結果の型は、両方のオペランドによって指定された型のすべての型修飾子で修飾された型へのポインタです。 C11規格で

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

@StephenCanonの引用はどうですか? –

+0

@PavanManjunath私はCとC++をもう一度混乱させました。私はそれを反映するために私の答えを更新しました。ありがとう! – dasblinkenlight

4

これは正当なCではありません。これを受け入れるコンパイラは間違っています。しかし、あなたが同じことを行うことができます。

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

、それが期待どおりにコンパイルし、実行している場合、それは最も可能性の高い有効だC.