在C,C ++中比较布尔变量与1和0是否安全?

时间:2014-03-19 18:18:56

标签: c++ c

考虑代码

bool f() { return 42; }

if (f() == 1)
    printf("hello");

C(C99 + with stdbool.h)和C ++标准是否保证"你好"会打印吗?确实

bool a = x;

总是等同于

bool a = x ? 1 : 0;

4 个答案:

答案 0 :(得分:2)

是。你错过了一步。 “0”为false,其他每个int都为true,但f()始终返回true(“1”)。它不返回42,铸造发生在“返回42;”。

答案 1 :(得分:2)

在C macro bool中(我们谈到stdbool.h中定义的宏)扩展为只有两个值0和1的_Bool

在C ++中,表达式f() == 1中f()的值根据整数提升隐式转换为int 1。

所以在我看来这段代码

bool f() { return 42; }

if (f() == 1)
    printf("hello");

是安全的。

答案 2 :(得分:2)

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

在1999 ISO C标准之前,C没有内置的布尔类型。程序员定义他们自己的布尔类型是(并且仍然是)常见的,例如:

typedef int BOOL;
#define FALSE 0
#define TRUE 1

typedef enum { false, true } bool;

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

C99添加了一个内置类型_Bool,其转换语义类似于C ++中bool的转换语义;如果您有bool,也可以将其称为#include <stdbool.h>

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

bool b;
*(char*)&b = 2;

将(可能)将值2存储在b中,但C ++编译器可能假设其值为0或{{1} };像1b == 0这样的比较可能会成功或失败。

我的建议:

  • 不要编写在b == true对象中存储奇怪值的代码。
  • 请勿将bool平等或不平等的值与bool01false进行比较。

在你的例子中:

true

假设这是C ++或带有bool f() { return 42; } 的C,此函数将返回<stdbool.h>或等同于true,因为1转换为42收益率bool

1

由于您尚未构建任何奇怪的if (f() == 1) printf("hello"); 值,因此表现良好且会打印bool

但明确地进行比较毫无意义。 "hello"已经是f()类型,因此它已经可用作条件。你可以(也可能应该)写下:

bool

撰写if (f()) printf("hello"); 并不比撰写f() == 1更有帮助。

在一个真实的程序中,大概你会给你的函数一个有意义的名字,清楚地表明它的值代表一个条件:

(f() == 1) == 1)

答案 3 :(得分:0)

我所知道的唯一真正的技巧,对于C99之前的环境很有用,是双重否定

int a = 42;
if ( (!!a) != 0 ) printf("Hello\n");

这将打印Hello,因为!!操作的结果是值为非零时为true的布尔值,否则为false。但是这要花费你2个否定来获得你想要的布尔值,在现代标准中这是多余的,因为没有!!你将获得相同的结果,而且这是语言授予的结果。