Code Fix

初級

if文の条件式で = と == を間違えて常に真になる

比較のつもりで==と書くべきところを=と書いてしまうと、比較ではなく代入になり、条件は代入した値の真偽で判定されます。エラーにはならず、意図しない分岐が起こります。

なぜエラーが出ないのか

出力: yes(okが0のはずなのに実行される)
(エラーなし)
Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: yes(okが0のはずなのに実行される)
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int ok = 0;
 5      if (ok =   1) {
                ^
 6          printf("yes\n");
 7      }
 8      return 0;
 9  }
出力: yes(okが0のはずなのに実行される)期待: 何も表示されない

if (ok = 1)は比較ではなく代入です。okに1が代入され、その代入結果(1)が真として評価されるため、常にブロックが実行されます。

直し方: = を == にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int age = 15;
 5      if (age =   18) {
                 ^
 6          printf("adult\n");
 7      } else {
 8          printf("minor\n");
 9      }
10      return 0;
11  }
出力: adult(15歳なのにadultと表示される)期待: minor

if (age = 18)はageに18を代入したうえで、その値(18、真)を条件として使ってしまいます。ageの実際の値である15は無視されます。

直し方: = を == にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int found = 0;
 5      if (found =  1) {
                   ^
 6          printf("found\n");
 7      } else {
 8          printf("not found\n");
 9      }
10      return 0;
11  }
出力: found(foundは0のはず)期待: not found

=は代入、==は比較です。1文字の書き間違いですが、Cはこれを文法的に正しい式として受け入れてしまうため、エラーにはなりません。

直し方: = を == にします。

この問題を解いてみる →

パターン4

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int active = 0;
 5      if (active =   1) {
                    ^
 6          printf("running\n");
 7      } else {
 8          printf("stopped\n");
 9      }
10      return 0;
11  }
出力: running(activeは0のはず)期待: stopped

if (active = 1)はactiveに1を代入し、その結果(真)を条件として使ってしまいます。

直し方: = を == にします。

この問題を解いてみる →

パターン5

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int level = 3;
 5      if (level =  5) {
                   ^
 6          printf("max\n");
 7      } else {
 8          printf("not max\n");
 9      }
10      return 0;
11  }
出力: max(levelは3のはず)期待: not max

levelの実際の値(3)に関わらず、代入された5が真として扱われてしまいます。

直し方: = を == にします。

この問題を解いてみる →

よくある誤解

Pythonでは代入を式の中で使えないため構文エラーになりますが、Cでは代入も1つの式として値を持つため、if文の条件式にそのまま書けてしまいます。0以外の値は真と評価されるため、多くの場合そのまま「常に真」になります。

実務での勘所

この事故を機械的に防ぐ手立てが2つあります。1つはコンパイラの警告オプション(-Wallに含まれる-Wparentheses)を有効にすることで、if (x = y)のような代入を条件式に書くと警告してくれます。もう1つは、比較の左右を入れ替えて定数を左に置く書き方(if (5 == x)のような、通称Yoda記法)です。誤って=と打ってもif (5 = x)はエラーになるため、コンパイラがそのミスを強制的に検出してくれます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)