これは、私自身の好奇心を満足させるための、純粋に衒学的な質問です。
私は質問で後者のオプションを使用する傾向がありますが(つまり、if (boolCheck) { ... }
)、同僚は常に前者を書き込みます(if (boolCheck == true) { ... }
)。私はいつも彼にそれについて少しからかいました、そして彼はいつも彼が最初にプログラミングを始めたときからそれを古い習慣として説明しました。
しかし、今日私は、== true
演算子を含む式はブール値に評価されるため、実際に==
部分全体を書き出すには処理のための追加の手順が必要になる場合があることに気付きました。これは本当ですか?
言い換えれば、私が理解しているように、オプションなし==真の線は次のように大まかに説明できます。
オプションwith == true行は次のようになります。
私は正しいですか?それとも、通常のコンパイラ/インタプリタはこの違いをなくしますか?それとも私は何かを見落としていますか、そして本当に違いはまったくありませんか?
明らかに、実際に観察されたパフォーマンスに関しては違いはありません。私が言ったように、私はただ興味があります。
編集: 2つのアプローチ間で手順が異なるかどうかを説明するためにコンパイルされた結果を実際に投稿してくれたすべての人に感謝します。 (ほんのわずかではありますが、ほとんどの場合、そうであったようです。)
私はではなく「正しい」アプローチとは何かについて質問していたことを繰り返し述べたいと思います。多くの人がどちらか一方を好むことを理解しています。また、論理的には、この2つは同一であることも理解しています。 CPUによって実行されている実際の操作が、両方のメソッドでまったく同じであるかどうかだけが気になりました。結局のところ、多くの場合(明らかに、言語やコンパイラなどに依存します)、そうではありません。
コンパイラは同じコードを生成する必要があります。ただし、trueと比較すると、より明確になるため、間違いなく優れています。一般的に私は明示的な比較をしませんが、あなたはそれをするために彼をからかうべきではありません。
編集:伝える最も簡単な方法は試してみることです。 MSコンパイラ(cl.exe)は、アセンブリで同じ数のステップを生成します。
int _tmain(int argc, _TCHAR* argv[])
{
bool test_me = true;
if (test_me) {
004113C2 movzx eax,byte ptr [test_me]
004113C6 test eax,eax
004113C8 je wmain+41h (4113E1h)
printf("test_me was true!");
}
if (test_me == true) {
004113E1 movzx eax,byte ptr [test_me]
004113E5 cmp eax,1
004113E8 jne wmain+61h (411401h)
printf("still true!");
}
return 0;
}
この時点での問題は、testとcmpのコストが同じかどうかです。専門家は違いを指摘できるかもしれませんが、私の推測はイエスです。
実際の結果は、これについて心配する必要はないということです。おそらく、はるかに大きなパフォーマンスの魚を揚げることができます。
真との比較は、あなたのパートナーによる理解の欠如を示していると思います。これを避けるために、本には名前を付ける必要があります(isAvaliable
:if (isAvailable) {...}
など)。
私は、その違いが、まともなコンパイラーによって最適化されることを期待しています。
(C#で確認したところ、コンパイルされたコードは両方の構文でまったく同じです。)
重複する質問( `!IsGood`またはʻIsGood == false`を使用する必要がありますか? )。これが私の前の答えへのポインタです:
問題の変数が実際にブール値として使用されることになっている場合(その型がブール値でなくても)、特にC/C++では、特にtrueまたはfalseに対してテストする手法は悪い習慣です。真に対してテストすると、微妙なバグが発生する可能性があります(おそらくそうなるでしょう)。
詳細については、次のSO回答を参照してください。
`!IsGood`またはʻIsGood == false`を使用する必要がありますか?
これは、Stroustrupの説明を含め、「== true」がしばしばfalseである理由の背後にある理由を詳細に説明するスレッドです。 https://qt-project.org/forums/viewthread/32642
私の経験では、if (flag==true)
は悪い習慣です。
最初の引数はアカデミックです:
_bool flag
_がある場合は、true
またはfalse
のいずれかです。
さて、式
_(flag==true)
_
繰り返しになりますが、true
またはfalse
です。これは表現力がなく、冗長であるだけです。flag
は、これまで以上に「より真」または「より偽」になることはできません。 flag
がブール値であることが明らかでない場合にのみ、「より明確」になります-しかし、すべてのタイプで機能するものを修正する標準的な方法があります:より良い名前を選択してください。
これを理由を超えて拡張すると、次のことが「さらに良く」なります。
_((flag==true)==true)
_
2番目の引数は実用的でプラットフォーム固有です
Cおよび初期のC++実装には実際の「ブール」型がなかったため、フラグにはさまざまな規則があり、最も一般的なのはゼロ以外のすべてが真であるということです。 APIが整数ベースのBOOL型を返すことは珍しくありませんが、戻り値を0または1に強制することはありません。
一部の環境では、次の定義を使用します。
_#define FALSE 0
#define TRUE (!FALSE)
_
if ((1==1) == TRUE)
で頑張ってください
さらに、一部のプラットフォームは異なる値を使用します-例: VB相互運用機能はshort
、_VARIANT_BOOL
_は_VARIANT_TRUE
_の_-1
_です。
これらの定義を使用してライブラリを混合する場合、trueとの明示的な比較は、善意を装ったエラーになりがちです。だから、しないでください。
これがPython(2.6)逆アセンブリです:
>>> def check(x): return (bool(x) == True)
>>> import dis
>>> dis.dis(check)
1 0 LOAD_GLOBAL 0 (bool)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 LOAD_GLOBAL 1 (True)
12 COMPARE_OP 2 (==)
15 RETURN_VALUE
>>> def check2(x): return bool(x)
>>> dis.dis(check2)
1 0 LOAD_GLOBAL 0 (bool)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 RETURN_VALUE
check
が最適化されていない理由は、Pythonが動的言語であるためだと思います。これ自体は、Pythonが使用するという意味ではありません。貧弱なコンパイラですが、ここで少し型推論を行うのに耐えることができます。pydファイルが作成されるときに違いが生じる可能性がありますか?
MSVC++ 6.0コンパイラは、次の2つの形式に対してわずかに異なるコードを生成します。
4: if ( ok ) {
00401033 mov eax,dword ptr [ebp-8]
00401036 and eax,0FFh
0040103B test eax,eax
0040103D je main+36h (00401046)
....
7: if ( ok == true ) {
00401046 mov ecx,dword ptr [ebp-8]
00401049 and ecx,0FFh
0040104F cmp ecx,1
00401052 jne main+4Bh (0040105b)
私が8086のタイミングを正しく覚えていれば、前のバージョンは非常にわずかに速いはずです:-)
これは、特定の言語と、彼らが「真実の」価値と見なすものに入ります。一般的なものは2つあります: JavaScript と [〜#〜] php [〜#〜] 。
これらの両方の言語のトリプル等号演算子は、ブール型の真理を実際にチェックしていることを保証します。たとえば、PHP if ($value)
のチェックはif ($value==true)
またはif ($value===true)
とは異なる場合があります。
$f = true;
$z = 1;
$n = null;
$a = array(1,2);
print ($f) ?'true':'false'; // true
print ($f==true) ?'true':'false'; // true
print ($f===true) ?'true':'false'; // true
print "\n";
print ($z) ?'true':'false'; // true
print ($z==true) ?'true':'false'; // true
print ($z===true) ?'true':'false'; // false
print "\n";
print ($n) ?'true':'false'; // false
print ($n==true) ?'true':'false'; // false
print ($n===true) ?'true':'false'; // false
print "\n";
print ($a) ?'true':'false'; // true
print ($a==true) ?'true':'false'; // true
print ($a===true) ?'true':'false'; // false
print "\n";
print "\n";
毎日話す言語が、この質問をどのように見ているかを教えてくれることを期待しています。
テストしている変数の名前によっては、「boolCheck == true」構文に正当化がある場合があります。
たとえば、変数名が「state」の場合、次のいずれかになります。
if (state) {
...
}
またはあなたが持つことができます
if (state == true) {
...
}
この場合、後者の形式の方がより明確で明白だと思います。
別の例は、「有効」のような変数です。この場合、最初の形式がより明確になります。
「state」と呼ばれるブール変数を持つことは悪い習慣ですが、それを制御できない場合があります。その場合、「== true」構文によってコードの可読性が向上する可能性があります。
Trueと等しいかどうかをテストすると、少なくともCではバグが発生する可能性があります。Cでは、「if」を整数型(ブール型だけでなく)で使用でき、any非ゼロ値を受け入れることができます。 ;ただし、記号「TRUE」は1つの特定のゼロ以外の値です(例:1
)。これはビットフラグで重要になる可能性があります。
if (flags & DCDBIT)
{
//do something when the DCDBIT bit is set in the flags variable
}
したがって、このような関数が与えられます...
int isDcdSet()
{
return (flags & DCDBIT);
}
...式「if(isDcdSet())」は「if(isDcdSet()== TRUE)」と同じではありません。
とにかく;最適化コンパイラは、(整数だけでなく)真のブール型の言語であると仮定して、(論理的な違いがないため)違いを最適化する必要があると思います。
コンパイラによって異なります。どちらの場合も最適化される可能性があります。
Null許容ブール値を使用している場合は、同じではない可能性があります。
例:
Bool? myBool = true
if(myBool) // This will not compile
if(myBool == true) //this will compile
単純な理由で、if (boolCheck == true)
形式を使用することはお勧めできません。誤って二重ではなく単一の「等号」を入力した場合(つまり、if (boolCheck = true)
)、 true
からboolCheck
になり、常にtrueが返されますが、これは明らかにバグです。もちろん、最近のほとんどのコンパイラーは、それを見ると警告を表示します(少なくとも、C#コンパイラーは表示します)が、多くの開発者は警告を無視します...
明示的にしたい場合は、次の形式を選択する必要があります:if (true == boolCheck)
。これにより、変数が誤って割り当てられるのを防ぎ、「等号」を忘れるとコンパイルエラーが発生します。
Fstreamのテストなど、内部型キャストが行われていないことを前提として、論理的な違いはありません。
ifstream fin;
...
if( ! fin)
...