Is it safe to compare boolean variable with 1 and 0 in C, C++? [duplicate]

守給你的承諾、 提交于 2021-02-20 19:13:19

问题


Consider the code

bool f() { return 42; }

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

Does C (C99+ with stdbool.h) and C++ standards guarantee that "hello" will printed? Does

bool a = x;

is always equivalent to

bool a = x ? 1 : 0;

回答1:


In C++, bool is a built-in type. Conversions from any type to bool always yield false (0) or true (1).

Prior to the 1999 ISO C standard, C did not have a built-in Boolean type. It was (and still is) common for programmers to define their own Boolean types, for example:

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

or

typedef enum { false, true } bool;

Any such type is at least 1 byte in size, and can store values other than 0 or 1, so equality comparisons to 0 or 1 are potentially unsafe.

C99 added a built-in type _Bool, with conversion semantics similar to those for bool in C++; it can also be referred to as bool if you have #include <stdbool.h>.

In either C or C++, code whose behavior is undefined can potentially store a value other than 0 or 1 in a bool object. For example, this:

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

will (probably) store the value 2 in b, but a C++ compiler may assume that its value is either 0 or 1; a comparison like b == 0 or b == true may either succeed or fail.

My advice:

  • Don't write code that stores strange values in bool objects.
  • Don't compare bool values for equality or inequality to 0, 1, false, or true.

In your example:

bool f() { return 42; }

Assuming this is either C++ or C with <stdbool.h>, this function will return true or, equivalently, 1, since the conversion of 42 to bool yields 1.

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

Since you haven't constructed any strange bool values, this is well behaved and will print "hello".

But there's no point in making the comparison explicitly. f() is already of type bool, so it's already usable as a condition. You can (and probably should) just write:

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

Writing f() == 1 is no more helpful than writing (f() == 1) == 1).

In a real program, presumably you'll have given your function a meaningful name that makes it clear that its value represents a condition:

if (greeting_required())
    printf("hello");



回答2:


Yes. You are missing a step though. "0" is false and every other int is true, but f() always returns true ("1"). It doesn't return 42, the casting occurs in "return 42;".




回答3:


In C macro bool (we are speaking about the macro defined in stdbool.h) expands to _Bool that has only two values 0 and 1.

In C++ the value of f() in expression f() == 1 is implicitly converted to int 1 according to the integral promotion.

So in my opinion this code

bool f() { return 42; }

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

is safe.




回答4:


The only real trick that I know of, that is useful with pre-C99 environments is the double negation

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

this will print Hello because the result of the !! operation is a boolean that is true when the value is non-zero, false otherwise. But this is gonna cost you 2 negation to get the boolean that you want, in modern standards this is redundant because you will get the same result without the !! and it's a result granted by the language.



来源:https://stackoverflow.com/questions/22514775/is-it-safe-to-compare-boolean-variable-with-1-and-0-in-c-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!