1.. title:: clang-tidy - readability-implicit-bool-conversion 2 3readability-implicit-bool-conversion 4==================================== 5 6This check can be used to find implicit conversions between built-in types and 7booleans. Depending on use case, it may simply help with readability of the code, 8or in some cases, point to potential bugs which remain unnoticed due to implicit 9conversions. 10 11The following is a real-world example of bug which was hiding behind implicit 12``bool`` conversion: 13 14.. code-block:: c++ 15 16 class Foo { 17 int m_foo; 18 19 public: 20 void setFoo(bool foo) { m_foo = foo; } // warning: implicit conversion bool -> int 21 int getFoo() { return m_foo; } 22 }; 23 24 void use(Foo& foo) { 25 bool value = foo.getFoo(); // warning: implicit conversion int -> bool 26 } 27 28This code is the result of unsuccessful refactoring, where type of ``m_foo`` 29changed from ``bool`` to ``int``. The programmer forgot to change all 30occurrences of ``bool``, and the remaining code is no longer correct, yet it 31still compiles without any visible warnings. 32 33In addition to issuing warnings, fix-it hints are provided to help solve the 34reported issues. This can be used for improving readability of code, for 35example: 36 37.. code-block:: c++ 38 39 void conversionsToBool() { 40 float floating; 41 bool boolean = floating; 42 // ^ propose replacement: bool boolean = floating != 0.0f; 43 44 int integer; 45 if (integer) {} 46 // ^ propose replacement: if (integer != 0) {} 47 48 int* pointer; 49 if (!pointer) {} 50 // ^ propose replacement: if (pointer == nullptr) {} 51 52 while (1) {} 53 // ^ propose replacement: while (true) {} 54 } 55 56 void functionTakingInt(int param); 57 58 void conversionsFromBool() { 59 bool boolean; 60 functionTakingInt(boolean); 61 // ^ propose replacement: functionTakingInt(static_cast<int>(boolean)); 62 63 functionTakingInt(true); 64 // ^ propose replacement: functionTakingInt(1); 65 } 66 67In general, the following conversion types are checked: 68 69- integer expression/literal to boolean (conversion from a single bit bitfield 70 to boolean is explicitly allowed, since there's no ambiguity / information 71 loss in this case), 72 73- floating expression/literal to boolean, 74 75- pointer/pointer to member/``nullptr``/``NULL`` to boolean, 76 77- boolean expression/literal to integer (conversion from boolean to a single 78 bit bitfield is explicitly allowed), 79 80- boolean expression/literal to floating. 81 82The rules for generating fix-it hints are: 83 84- in case of conversions from other built-in type to bool, an explicit 85 comparison is proposed to make it clear what exactly is being compared: 86 87 - ``bool boolean = floating;`` is changed to 88 ``bool boolean = floating == 0.0f;``, 89 90 - for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``, 91 ``0.0``, ``nullptr``), 92 93- in case of negated expressions conversion to bool, the proposed replacement 94 with comparison is simplified: 95 96 - ``if (!pointer)`` is changed to ``if (pointer == nullptr)``, 97 98- in case of conversions from bool to other built-in types, an explicit 99 ``static_cast`` is proposed to make it clear that a conversion is taking 100 place: 101 102 - ``int integer = boolean;`` is changed to 103 ``int integer = static_cast<int>(boolean);``, 104 105- if the conversion is performed on type literals, an equivalent literal is 106 proposed, according to what type is actually expected, for example: 107 108 - ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``, 109 110 - ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``, 111 112 - for other types, appropriate literals are used (``false``, ``true``, ``0``, 113 ``1``, ``0u``, ``1u``, ``0.0f``, ``1.0f``, ``0.0``, ``1.0f``). 114 115Some additional accommodations are made for pre-C++11 dialects: 116 117- ``false`` literal conversion to pointer is detected, 118 119- instead of ``nullptr`` literal, ``0`` is proposed as replacement. 120 121Occurrences of implicit conversions inside macros and template instantiations 122are deliberately ignored, as it is not clear how to deal with such cases. 123 124Options 125------- 126 127.. option:: AllowIntegerConditions 128 129 When non-zero, the check will allow conditional integer conversions. Default 130 is `0`. 131 132.. option:: AllowPointerConditions 133 134 When non-zero, the check will allow conditional pointer conversions. Default 135 is `0`. 136