20

C プロジェクト (OpenVPN が問題のプロジェクトで、コミット4029971240b6274b9b30e76ff74c7f689d7d9750 ) では、bool のエミュレーションがありました。

typedef int bool;
#define false 0
#define true 1

C99 bool に切り替えます

#include <stdbool.h>

しかし、プロジェクトには、ブールの不適切な使用法がどこかにあります。std bool の動作が異なることは知っています。例えば

bool t;

t=2;
if ( t == true)
    printf("True!\n");
else
    printf("False!\n");

True を返します! とstdbool.h偽!#defineエミュレーションで。

私の質問stdbool とエミュレートされた bool で異なる動作をするこれらのコード部分を見つける方法はありますか? おそらく、私が見落としたいくつかのコンパイラフラグ、または差分をとることができる優れたllvmまたはgcc中間フォーマットですか?

上記の例ほど単純ではありませんが、見にくいものでなければなりません。== true ではないことは間違いありません。

更新: 問題が見つかりました (mbuf_set には int メンバー len があります)。ちょっとばかげていますが、これらをどのようにキャッチするかという問題はまだ残っています。整数オーバーフロー チェックが次のようなものをキャッチしないことに驚いています。

 static inline bool
 mbuf_len (const struct mbuf_set *ms)
 {
   return ms->len;
 }
4

1 に答える 1

2

あなたが説明している種類の使用法は正しく、明確に定義された動作です。したがって、コンパイラは警告を生成しません。これを回避する方法の 1 つは、次のように変更することtypedefです。

typedef enum {false, true} bool;

これにより、(適切に定義されているため) エラーなしでコードをコンパイルできますが、コンパイラまたはアナライザーからの警告を強制できる場合があります。たとえば、次のようにclangすると、この種のものを拾うことができ-Weverythingます:

$ clang -o a a.c -Weverything
a.c:7:11: warning: integer constant not in range of enumerated type 'bool'
      [-Wassign-enum]
        bool n = 2;

もちろん、これは実行時チェックを行いません。typedefbool 変数を 0 または 1 以外の値に変更することは引き続き許可されます (たとえば、関数呼び出しまたは式で)。これらのインスタンスを検出する唯一の方法は、デバッガーを使用することです。

true と false のマクロは、stdbool.h実際には型専用に設計されてい_Boolます。これは、この型が値 0 と 1 しか保持できないためです。0 以外の値を割り当てると、1 として保存されます。したがって、ブール型の場合のみ、true および false マクロが機能することが保証されます。

型がなければ_Bool、言語自体にこれを直接実行させる方法はありません。これは、同等の型がないためです。事実上、それ2 == 1が true を返すことを許可するように要求することになります。

同じ動作を実装する方法がいくつかあります。たとえばBOOL(n)、 variable を使用するすべてのインスタンスでマクロを使用してn、その値が 0 または 1 のみであることを確認します。_Boolこのように、 for を使用してもintforを使用しても、同じ結果が得られますn。例えば:

#define BOOL(n) ((n) != 0 ? 1 : 0 )

bool b = rand() % 100;

if (BOOL(b) == true) ...

これはstdbool、またはを使用するかどうかに関係なく機能しtypedefます。

于 2013-03-11T13:32:43.400 に答える