BOOLまたはBOOLEAN-それが問題ですか?

どういうわけか私はブールまたはブールを使用する方が良いとは思わなかった? もちろん、BOOLはより短く、BOOLはすべてのWindowsチュートリアルにあります。 どんなに! ちょうど昨日、私は1時間かけて、エラーが発生してはならないエラーを探しました。

C ++言語標準で定義されているブール型に直接関連する唯一の真の型はブール型であることが判明しました。 BOOLは「typedef int BOOL」にすぎず、windows.hにあります(より正確にはWinDef.hにありますが、重要ではありません)

2つの数値を比較する関数のソースコードをさらに詳しく考えてみましょう。
#include <stdio.h> #include <windows.h> bool CompareInt(int i1, int i2) { if (i1==i2) return true; //UPD1:  TRUE else return false; //UPD1:  FALSE } typedef BOOL (*CallBack)(int, int); void main(void) { CallBack IsEqual = (CallBack)CompareInt; if ( !IsEqual(0x1234, 0x5678) ) printf("Not equals"); else printf("Equals"); } 
Visual Studioをコンパイルして起動すると、次のようになります。

次に、ブールをブールに変更します。
 typedef BOOLEAN (*CallBack)(int, int); 
コンパイル、実行、取得:等しくない(最初から正しいはずでした)

結論:BOOLは使用せず、BOOLEANのみを使用してください。

UPD1:リターン関数で修正され、実験の純度に対してTRUE / FALSEがtrue / falseになりました。

UPD2: 「ブラックマジック」を明らかにします。 boolはchar型(CPU alレジスタ)で返されます。これは、Visual Studioのboolがcharと等しいためです(BOOLEANもcharと同じであるため、BOOLをBOOLEANに置き換えるとエラーが削除されます)。

しかし、BOOL型はint(eaxレジスタ)と等しいため、関数がfalse(false)を返すと、下位バイトalのみがゼロに設定され、上位バイト(ahおよび他のeax)がゼロ以外のゴミになります。 boolの結果を組み込むBOOLはeax!= 0のように反応し、エラーが発生します。

CompareInt関数が0に等しいアルと最も古い(ガベージ)バイトだけを返したため、最後のif内でeax == 0(等しくない)でブランチに移動し、eaxで分岐に切り替えなければなりません!= 0(等しい)この場合のCompareInt関数内のeaxでは(誤って?)0に設定されていません。

UPD3:ところで、Borland Builder C ++は古代(2006)でこのコードをコンパイルしました。CompareInt関数内でfalseが返されると、すべてのeaxビットはxor eax、eaxによって明示的に0に設定されます。したがって、エラーはありません。

Source: https://habr.com/ru/post/J135490/


All Articles