rspec/rules/S867/rule-except-see.adoc

55 lines
2.3 KiB
Plaintext

There are several constructs in the language that work with boolean:
* If statements: ``++if (b) ...++``
* Conditional operator: ``++int i = b ? 0 : 42;++``
* Logical operators: ``++(b1 || b2) && !b3++``
Those operations would also work with arithmetic or enum values operands, because there is a conversion from those types to bool. However, this conversion might not always be obvious, for instance, an integer return code might use the value ``++0++`` to indicate that everything worked as expected, but converted to boolean, this value would be ``++false++``, which often denotes failure. Conversion from integer to bool should be explicit.
Moreover, a logical operation with integer types might also be a confusion with the bitwise operators (``++&++``, ``++|++`` and ``++~++``).
Converting a pointer to ``++bool++`` to check if it is null is idiomatic and is allowed by this rule. We also allow the use of any user-defined type convertible to bool (for instance ``++std::ostream++``), since they were specifically designed to be used in such situations. What this rule really detects is the use or arithmetic types (``++int++``, ``++long++``...) and of enum types.
On the other hand, arithmetic operations are defined with booleans, but usually make little sense (think of adding two booleans). Booleans should not be used in an arithmetic context.
Finally, comparing a boolean with the literals ``++true++`` or ``++false++`` is unnecessarily verbose, and should be avoided.
=== Noncompliant code example
[source,text]
----
if ( 1 && ( c < d ) ) // Noncompliant
if ( ( a < b ) && ( c + d ) ) // Noncompliant
if ( u8_a && ( c + d ) ) // Noncompliant
if ( !0 ) // Noncompliant, always true
if ( !ptr ) // Compliant
if ( ( a < b ) && ( c < d ) ) // Compliant
if ( !false ) // Compliant
if (!!a) // Compliant by exception
if ( ( a < b ) == true) // Noncompliant
----
=== Compliant solution
[source,text]
----
if ( 1 != 0 && ( c < d ) ) // Compliant, but left operand is always true
if ( ( a < b ) && ( c + d ) != 0 ) // Compliant
if ( u8_a != 0 && ( c + d ) != 0) // Compliant
if ( 0 == 0 ) // Compliant, always true
if ( a < b )
----
=== Exceptions
Some people use ``++!!++`` as a shortcut to cast an integer to bool. This usage of the ``++!++`` operator with an integer argument is allowed for this rule.