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