【C/C++】C2106「左のオペランドが左辺値になっていません」の原因と対処法

プログラムを書いてコンパイルしようとするとif文の行がC2106「左のオペランドが左辺値になっていません」となってエラーメッセージが表示されることがあります。

正しく条件式を書いているはずなのにバグが起きているように見えるC2106エラーは、プログラミング初心者に限らず中級者でも行ってしまいがちです。

今回はC2106「左のオペランドが左辺値になっていません」の原因と対処法を解説していきます。

目次から探す

C2106エラーが発生する原因

C2106「左のオペランドが左辺値になっていません」が発生する原因は、if文などで比較式を書いているにも関わらず、タイプミスで代入式になってしまっていることが原因です。

以下のコードの4行目をよく見てください。

int main() {
    int a = 10;
    int b = 5;
    if(a > 0 && b = 5){
        return 1;
    }
    return 0;
}

プログラムを書いた本人は「aが0以上かつbが5なら1を返す」という処理を組んだつもりでいますが、2つ目の条件式が”==”ではなく”=”になっており、代入式になってしまっています。

正しくは以下のように”==”にして「bが5ならtrue(真)」とする必要があります。

if(a > 0 && b == 5){

こうしないとC2106「左のオペランドが左辺値になっていません」が発生してしまうので注意してください。

C2016エラーが発生しないときもある(かなり危険)

C2106エラーによってコンパイルに失敗する時は必ずといっていいほど2つ以上の条件式があるときです。

以下のコードの場合はエラーが発生せずコンパイルが成功し、実行もできてしまいます。

int main() {
    int b = 5;
    if(b = 5){
        return 1;
    }
    return 0;
}

この式にしてしまうと代入され値が0以外のときはif文を実行するため、ほとんどの場合においてバグの原因になります。

幸いにも最新のVisual Studioでは、

C6282「不適切な演算子です; ブール値のコンテキストの定数が代入式です。代わりに’==’を使用してください。」
LNT1002「おそらく演算子’==’が意図されている場面で、代入’=’が使用されています」

と警告メッセージが表示されるようになっています。

同様の警告を確認したらすぐに修正するようにしてください。放置すればするほど気づきにくいバグになってしまうでしょう。

‘=’と書いてしまったときに強制的にエラーを起こさせる書き方

条件式が2つ以上書かれている場合であればコンパイルエラーとなるのですぐに気づくことができますが、条件式が一つのときに’=’と書き間違えてしまうとただの代入式となってしまい、コンパイルが通ってしまいます。

‘=’が一つ抜けて代入式になってしまうミスはプログラミング中級者でもやってしまいがちなミスで、バグ探しで盲点になりやすいポイントです。

そこで、間違えて’=’が一つ抜けてしまったときに強制的にエラーを起こしてコンパイルに失敗する方法を紹介します。

代入式は「左にある変数に右の値を代入する」という決まりがあり、その逆は認められていません。そのため以下の代入式はエラーになります。

int a;
10 = a; //10は定数なので代入できない

この仕組みを応用して変数を右側、代入できない定数を左側に持ってくることでタイプミスに気づきやすくなります。

int main() {
    int b = 5;

    //有効な条件式(エラーにならない正しい書き方
    if (-1 == b) {
        return 1;
    }

    //定数に代入することは不可能なのでエラーになる
    if(-1 = b){
        return 1;
    }
    return 0;
}

条件式が「変数A = 変数B」の場合は意味がありませんが、「変数A == 100」といった片方が定数になる条件式になる場合は有効な方法なので覚えておくと良いでしょう。

エラーが出ない時のバグ修正がかなり大変

今でこそ間違えて’=’が一つ抜けて代入式になってしまっても警告が出るようになっていますが、警告が出ないバグというのはたくさんあります。

コンパイルエラーになるバグや警告が出るバグであれば修正しやすいですが、警告が一切でないバグは特定が難しいので、できるだけ「一つ書き間違えたらエラーが発生してコンパイルに失敗する書き方」を心がけるようにするとミスをしてもすぐに修正できるようになります。

プログラミングにバグはつきものですので、バグを発見しやすい書き方を意識するといいでしょう。

目次から探す