问题
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 to0
,1
,false
, ortrue
.
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