web-dev-qa-db-ja.com

式は変更可能な左辺値でなければなりません

私はこの次のコードを持っています:

int M = 3; 
int C = 5; 
int match = 3;
for ( int k =0; k < C; k ++ )
{
    match --; 
    if ( match == 0 && k = M )
    {
         std::cout << " equals" << std::endl;
    }
}

ただし、次のようなエラーが表示されます。

エラー:式は変更可能な値である必要があります

その「if」行に。ここで「一致」または「k」の値を変更しようとはしていませんが、なぜこのエラーですか?次のように書くだけなら:

if ( match == 0 )

大丈夫です。誰かが私にそれを説明できますか?

23
E_learner

代入演算子の優先順位は&&よりも低いため、条件は次と同等です。

if ((match == 0 && k) = m)

ただし、この左側は右辺値、つまり副式match == 0 && kの評価の結果のブール値であるため、それに割り当てることはできません。

対照的に、比較の優先順位は高いため、match == 0 && k == mは次と同等です。

if ((match == 0) && (k == m))
31
Kerrek SB

Cでは、次を宣言した場合にも同じエラーが発生します。

char array[size];

そして、インデックス位置を指定せずに値を割り当てようとします:

array = '\0'; 

実行することにより:

array[index] = '0\';

以前に宣言したアクセス可能/変更可能なアドレスを指定しています。

16
Alan

単一の=は常にCまたはC++の割り当てであることに注意してください。

テストは、if ( match == 0 && k == M )k == Mテストでタイプミスを行ったはずです。

本当にk=M(つまり、テスト内の副作用の割り当て)を意味する場合は、読みやすさの理由でコードif (match == 0 && (k=m) != 0)を使用する必要がありますが、ほとんどのコーディング規則はそれを記述しないことを推奨します。

ところで、あなたの間違いは、すべての警告を要求する(例えば、-Wallg++オプション)、および最近のコンパイラにアップグレードすることを示唆しています。次のGCC 4.8では次のことが可能になります。

 % g++-trunk -Wall -c ederman.cc
 ederman.cc: In function ‘void foo()’:
 ederman.cc:9:30: error: lvalue required as left operand of assignment
          if ( match == 0 && k = M )
                               ^

clang 3.1はederman.cc:9:30: error: expression is not assignableも通知します

したがって、無料のコンパイラの最新バージョンを使用し、それらを使用するときにすべての警告を有効にしてください。

_k = M_の代わりに_k == M_をテストします。
たぶんあなたがしたいことです。この場合、if (match == 0 && (k = M))と書きます。

3
tomahh