This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 7.0.2 - There shall be no conversion to type bool
[conv.integral]
[conv.bool]
Category: Required
Analysis: Decidable,Single Translation Unit
Rationale
Conversion from a fundamental type (see [basic.fundamental]) to bool depends on the interpretation of a non-zero value as
true (see [conv.bool]). However, this interpretation may not be appropriate for APIs, such as POSIX, that do not use Boolean return
values.
Contextual conversion to bool occurs when an operand of fundamental type is used as:
- An operand to a logical operator; or
- The first operand of the conditional operator; or
- The condition of an if-statement or iteration-statement.
The result of such a conversion may not be what the developer intended (for example, when an assignment is accidentally used as the
condition to an if-statement). Therefore, wherever a contextual conversion to bool may occur, the corresponding expression
shall have type bool (e.g. as a result of an explicit test).
In addition, fundamental types, unscoped enumeration types [1], and pointers will be implicitly converted on assignment to
bool. The result of such implicit conversions may not be what the developer intended.
Exception
- A
static_cast to bool is permitted for a class type having an explicit operator bool.
- Contextual conversion to bool is permitted from a pointer, or from a
class type having an explicit operator
bool.
- A bit-field of size 1 can be converted to
bool — this is a common idiom used when accessing hardware registers and there is no
risk of confusion.
- In a while, a condition of the form type-specifier-seq declarator is not required to have type
bool as
alternative mechanisms for achieving the same effect generally require the scope of objects to be wider than necessary. Note that a similar
exception is not needed for the if statement, as the if ( //init-statement<sub>opt</sub>// //condition// ) syntax
was introduced in C++17.
Example
if ( ( u8a < u8b ) && ( u8c < u8d ) ) // Compliant
if ( ( u8a < u8b ) && ( u8c + u8d ) ) // Non-compliant
if ( true && ( u8c < u8d ) ) // Compliant
if ( 1 && ( u8c < u8d ) ) // Non-compliant
if ( u8a && ( u8c < u8d ) ) // Non-compliant
if ( !0 ) // Non-compliant
if ( !false ) // Compliant
s32a = s16a ? s32b : s32c; // Non-compliant
s32a = b1 ? s32b : s32c; // Compliant
s32a = ( s16a < 5 ) ? s32b : s32c; // Compliant
int32_t fn();
bool fb();
while ( int32_t i1 = fn() ) // Compliant by exception #4
if ( int32_t i2 = fn() ) // Non-compliant
if ( int32_t i3 = fn() ; i3 != 0) // Compliant version of the above line
while ( std::cin ) // Compliant by exception #2 - std::istream
// has explicit operator bool
for ( int32_t x = 10; x; --x ) // Non-compliant
extern int32_t * getptr();
if ( getptr() ) // Compliant by exception #2 - contextual
// conversion from pointer to bool
bool b2 = getptr(); // Non-compliant
bool b3 = getptr() != nullptr; // Compliant
if ( bool b4 = fb() ) // Compliant
if ( int32_t i = fn(); i != 0 ) // Compliant
if ( int32_t i = fn(); i ) // Non-compliant - condition has type of 'i'
if ( int32_t i = fn() ) // Non-compliant
if ( u8 ) // Non-compliant
The following example illustrates contextual conversion to bool with a user-defined class type:
class C
{
int32_t x;
public:
explicit operator bool() const { return x < 0; }
};
void foo( C c )
{
bool b1 = static_cast< bool >( 4 ); // Non-compliant
bool b2 = static_cast< bool >( c ); // Compliant by exception #1
if ( c ) // Compliant by exception #2 - contextual
{ // conversion from 'C' to bool
}
}
Glossary
[1] Unscoped enumeration type
A type created with the enum keyword that is not created as enum class or enum struct. Values of such a type
will be subject to integral promotion.
Copyright The MISRA Consortium Limited © 2023