43

私は最近、入力ミスが原因であるコードのバグを見つけ出すのに時間を費やしました:

if (a=b)

それ以外の:

if (a==b)

ステートメント内の変数に値を割り当てたい特定のケースがあるかどうかif、またはそうでない場合、コンパイラが警告またはエラーをスローしないのはなぜですか?

4

8 に答える 8

19

代入演算子は、割り当てられた値の値を返します。したがって、次のような状況で使用できます。

if (x = getMyNumber())

xによって返される値を代入しgetMyNumber、それがゼロでないかどうかを確認します。

それは避けてください。これを理解するのを助けるために例を挙げました。

編集: ただの提案を追加します。

このようなバグを回避するには、一部の拡張まで、if 条件をif(NULL == ptr)代わりに書く必要if (ptr == NULL)があります。なぜなら、等値チェック演算子のスペルを operator と間違える===、コンパイルは左辺値エラーを でスローしますがif (NULL = ptr)if (res = NULL)コンパイラによって渡されます (これはあなたが意味するものではありません)。実行時のコードのバグのままです。

この種のコードに関する批判も読むべきです。

于 2013-07-16T16:06:30.670 に答える
6

最近、これが役立つケースに遭遇したので、投稿することにしました。

1 つの if で複数の条件をチェックし、いずれかの条件が true の場合にエラー メッセージを生成するとします。エラーの原因となった特定の条件をエラー メッセージに含めたい場合は、次のようにします。

std::string e;
if( myMap[e = "ab"].isNotValid() ||
    myMap[e = "cd"].isNotValid() ||
    myMap[e = "ef"].isNotValid() )
{
    // here, e has the key for which the validation failed
}

したがって、2 番目の条件が true と評価される場合、e は "cd" と等しくなります。||これは、標準で義務付けられている短絡動作によるものです (過負荷でない限り)。短絡の詳細については、この回答を参照してください。

于 2016-06-28T23:15:46.753 に答える
5

c++17 では、以下を使用できます。

if (<initialize> ; <conditional_expression>) { <body> }

for ループ イテレータ初期化子に似ています。

次に例を示します。

if (Employee employee = GetEmployee(); employee.salary > 100) { ... }
于 2021-04-27T10:29:24.853 に答える
2

で割り当てを行うことifはかなり一般的なことですが、人々が偶然にそれを行うことも一般的です。

通常のパターンは次のとおりです。

if (int x = expensive_function_call())
{
  // ...do things with x
}

アンチパターンは、誤って物事に割り当てている場所です。

if (x = 1)
{
  // Always true
}
else
{
  // Never happens
}

定数または値を最初に配置することで、これをある程度回避できるためconst、コンパイラはエラーをスローします。

if (1 = x)
{
  // Compiler error, can't assign to 1
}

===は、目を養う必要があるものです。私は通常、演算子の周りに空白を配置して、どの操作が実行されているかをより明確にします。一目でlongname=longernameよく似ていますが、それ自体は明らかに異なります。longname==longername===

于 2013-07-16T16:06:38.437 に答える