古いコードを新しいコンパイラでコンパイルしようとすると、次のエラーが発生しました。
error: cannot take the address of an rvalue of type 'int'
これは2行の例です-1つはコンパイルし、もう1つはエラーを出します
struct mstct {
int myfield;
int myfield2[5];
int myfield3[5];
};
typedef struct mstct db_data_px;
int foo(int a, int b, int c){
//the next code compiles successfully.
unsigned val1 = ((18 == c) ? ((unsigned) & (((db_data_px *) 0)->myfield)) : ((unsigned) & (((db_data_px *) 0)->myfield3[b]))); //successes
//the next code is failing
unsigned val2 = (unsigned) & ((18 == c) ? (((db_data_px *) 0)->myfield) : (((db_data_px *) 0)->myfield3[b]));
return 0; // failing
}
最初の行がコンパイルされ、2番目の行が失敗するのはなぜですか?選択式の両方で(符号なし)&をキャストする必要があり、選択式が評価された後にのみキャストするだけでは不十分なのはなぜですか?
あなたのコードで
((18 == c) ? (((db_data_px *) 0)->myfield) : (((db_data_px *) 0)->myfield3[b]))
左辺値を生成しない条件式です。
上記の式は右辺値(non-lvaue)を与え、その上で&
演算子を使用することはできません。
詳述すると、C11
標準、§6.5.3.2章、アドレスおよび間接演算子を引用します。
単項
&
演算子のオペランドは、関数指定子、[]
または単項*
演算子の結果、またはビットフィールドではないオブジェクトを指定する左辺値のいずれかでなければなりません。register
ストレージクラス指定子では宣言されていません。
OTOH、条件演算子の結果タイプについては、§6.5.15章の脚注
条件式は左辺値を生成しません。
想像してみてください、&5
、不可能です。