在 C、C++ 中将布尔变量与 1 和 0 进行比较安全吗?

5 c c++

考虑代码

bool f() { return 42; }

if (f() == 1)
    printf("hello");
Run Code Online (Sandbox Code Playgroud)

C(带有 stdbool.h 的 C99+)和 C++ 标准是否保证打印“hello”?做

bool a = x;
Run Code Online (Sandbox Code Playgroud)

总是等价于

bool a = x ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 2

在C++中,bool是内置类型。从任何类型到 的转换bool总是产生false(0) 或true(1)。

在 1999 年 ISO C 标准之前,C 没有内置布尔类型。程序员定义自己的布尔类型过去(现在仍然)很常见,例如:

typedef int BOOL;
#define FALSE 0
#define TRUE 1
Run Code Online (Sandbox Code Playgroud)

或者

typedef enum { false, true } bool;
Run Code Online (Sandbox Code Playgroud)

任何此类类型的大小至少为 1 个字节,并且可以存储除0或之外的值,因此与或 的1相等比较可能是不安全的。01

C99 添加了内置 type ,其转换语义与C++ 中的_Boolfor 类似;bool它也可以被称为“bool如果你有” #include <stdbool.h>

在 C 或 C++ 中,行为未定义的代码可能会在对象中存储 0 或 1 以外的值bool。例如,这个:

bool b;
*(char*)&b = 2;
Run Code Online (Sandbox Code Playgroud)

将(可能)将值存储2在 中b,但 C++ 编译器可能会假设其值是01b == 0类似or 的比较b == true可能成功也可能失败。

我的建议:

  • 不要编写在bool对象中存储奇怪值的代码。
  • 不要将bool相等或不等的值与01false或进行比较true

在你的例子中:

bool f() { return 42; }
Run Code Online (Sandbox Code Playgroud)

假设这是 C++ 或带有 的 C <stdbool.h>,该函数将返回trueor,等效地1,因为 的转换42bool产生1

if (f() == 1)
    printf("hello");
Run Code Online (Sandbox Code Playgroud)

由于您没有构造任何奇怪的bool值,因此表现良好并且会打印"hello".

但明确地进行比较是没有意义的。f()已经是类型bool,所以它已经可以用作条件。你可以(并且可能应该)只写:

if (f())
    printf("hello");
Run Code Online (Sandbox Code Playgroud)

写作f() == 1并不比写作更有帮助(f() == 1) == 1)

在真实的程序中,您可能会为函数指定一个有意义的名称,以明确其值代表一个条件:

if (greeting_required())
    printf("hello");
Run Code Online (Sandbox Code Playgroud)