11

古いコードを新しいコンパイラでコンパイルしようとしたところ、次のエラーが発生しました。

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 番目の行が失敗するのはなぜですか? select 式の両方で (unsigned) & をキャストする必要があるのはなぜですか? select 式が評価された後にのみキャストするだけでは不十分です。

4

1 に答える 1

9

あなたのコードで

   ((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不可能です。

于 2016-01-27T15:49:13.087 に答える