Casting Int to Bool in C/C++

Casting int to bool in C/C++

0 values of basic types (1)(2)map to false.

Other values map to true.

This convention was established in original C, via its flow control statements; C didn't have a boolean type at the time.


It's a common error to assume that as function return values, false indicates failure. But in particular from main it's false that indicates success. I've seen this done wrong many times, including in the Windows starter code for the D language (when you have folks like Walter Bright and Andrei Alexandrescu getting it wrong, then it's just dang easy to get wrong), hence this heads-up beware beware.


There's no need to cast to bool for built-in types because that conversion is implicit. However, Visual C++ (Microsoft's C++ compiler) has a tendency to issue a performance warning (!) for this, a pure silly-warning. A cast doesn't suffice to shut it up, but a conversion via double negation, i.e. return !!x, works nicely. One can read !! as a “convert to bool” operator, much as --> can be read as “goes to”. For those who are deeply into readability of operator notation. ;-)



1) C++14 §4.12/1 “A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.”

2) C99 and C11 §6.3.1.2/1 “When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.”

Why use !! when converting int to bool?

The problems with the "!!" idiom are that it's terse, hard to see, easy to mistake for a typo, easy to drop one of the "!'s", and so forth. I put it in the "look how cute we can be with C/C++" category.

Just write bool isNonZero = (integerValue != 0); ... be clear.

int to bool casting

int x ;
bool b1 = !!x; // common idiom; get used to it. "Newcomers" just need to learn the idiom.
bool b2 = x!=0; // another way, less idiomatic

Why does casting an int to a bool give a warning?

Just because the conversion a => b is implicit doesn’t say anything about the viability of the reverse, b => a.

In your case, you shouldn’t cast at all. Just do the obvious thing: compare:

bool result = int_value != 0;

This is the only logically correct way of converting an int to bool and it makes the code much more readable (because it makes the assumptions explicit).

The same applies for the reverse, by the way. Converting implicitly from bool to int is just lazy. Make the mapping explicit:

int result = condition ? 1 : 0;

Converting Int to Bool

No, there is and has never been an explicit built in option for conversion of Int to Bool, see the language reference for Bool for details.

There exists, still, however, an initializer by NSNumber. The difference is that implicit bridging between Swift numeric type and NSNumber has been removed in Swift 3 (which previously allowed what seemed to be explicit Bool by Int initialization). You could still access this by NSNumber initializer by explicitly performing the conversion from Int to NSNumber:

let number = 1
let result = Bool(number as NSNumber)

print(result) // true

As @Hamish writes in his comment below: if we leave the subject of initializers and just focus on the end result (instantiating a Bool instance given the value of an Int instance) we can simply make use of the != operator for Int values (specifically, the operator with signature func !=(lhs: Int, rhs: Int) -> Bool), a generalization easily achievable using the != operator approach:

let number = -1
let result = number != 0

print(result) // true

Much like you yourself as well as @JAL describes in his answer, you could construct your own Bool by Int initializer, but you might as well consider generalizing this for any type conforming to the Integer protocol:

extension Bool {
init<T: Integer>(_ num: T) {
self.init(num != 0)
}
}

/* example usage */
let num1: Int8 = -1
let num2: Int = 3
let num3: UInt64 = 0
// ....
let result1 = Bool(num1) // true
let result2 = Bool(num2) // true
let result3 = Bool(num3) // false

Can't cast int to bool

int and bool can't be converted implicitly (in contrast to C++, for example).

It was a concious decision made by language designers in order to save code from errors when a number was used in a condition. Conditions need to take a boolean value explicitly.

It is not possible to write:

int foo = 10;

if(foo) {
// Do something
}

Imagine if the developer wanted to compare foo with 20 but missed one equality sign:

if(foo = 20) {
// Do something
}

The above code will compile and work - and the side-effects may not be very obvious.

Similar improvements were done to switch: you cannot fall from one case to the other - you need an explicit break or return.

Is (bool) cast reliably 0 or 1?

C 2018 6.3.1.2 1 says:

When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.

How can I fix an int-to-bool warning in C++?

How about

accessLV[i] = FileRead(file1, i + 1) != 0;

Can I assume (bool)true == (int)1 for any C++ compiler?

According to the standard, you should be safe with that assumption. The C++ bool type has two values - true and false with corresponding values 1 and 0.

The thing to watch about for is mixing bool expressions and variables with BOOL expression and variables. The latter is defined as FALSE = 0 and TRUE != FALSE, which quite often in practice means that any value different from 0 is considered TRUE.

A lot of modern compilers will actually issue a warning for any code that implicitly tries to cast from BOOL to bool if the BOOL value is different than 0 or 1.



Related Topics



Leave a reply



Submit