xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/readability/simplify-boolean-expr.rst (revision 5295ca1a8e5844b44d6b4140ea46405301e9c63f)
1.. title:: clang-tidy - readability-simplify-boolean-expr
2
3readability-simplify-boolean-expr
4=================================
5
6Looks for boolean expressions involving boolean constants and simplifies
7them to use the appropriate boolean expression directly.  Simplifies
8boolean expressions by application of DeMorgan's Theorem.
9
10Examples:
11
12===========================================  ================
13Initial expression                           Result
14-------------------------------------------  ----------------
15``if (b == true)``                             ``if (b)``
16``if (b == false)``                            ``if (!b)``
17``if (b && true)``                             ``if (b)``
18``if (b && false)``                            ``if (false)``
19``if (b || true)``                             ``if (true)``
20``if (b || false)``                            ``if (b)``
21``e ? true : false``                           ``e``
22``e ? false : true``                           ``!e``
23``if (true) t(); else f();``                   ``t();``
24``if (false) t(); else f();``                  ``f();``
25``if (e) return true; else return false;``     ``return e;``
26``if (e) return false; else return true;``     ``return !e;``
27``if (e) b = true; else b = false;``           ``b = e;``
28``if (e) b = false; else b = true;``           ``b = !e;``
29``if (e) return true; return false;``          ``return e;``
30``if (e) return false; return true;``          ``return !e;``
31``!(!a || b)``                                 ``a && !b``
32``!(a || !b)``                                 ``!a && b``
33``!(!a || !b)``                                ``a && b``
34``!(!a && b)``                                 ``a || !b``
35``!(a && !b)``                                 ``!a || b``
36``!(!a && !b)``                                ``a || b``
37===========================================  ================
38
39The resulting expression ``e`` is modified as follows:
40  1. Unnecessary parentheses around the expression are removed.
41  2. Negated applications of ``!`` are eliminated.
42  3. Negated applications of comparison operators are changed to use the
43     opposite condition.
44  4. Implicit conversions of pointers, including pointers to members, to
45     ``bool`` are replaced with explicit comparisons to ``nullptr`` in C++11
46     or ``NULL`` in C++98/03.
47  5. Implicit casts to ``bool`` are replaced with explicit casts to ``bool``.
48  6. Object expressions with ``explicit operator bool`` conversion operators
49     are replaced with explicit casts to ``bool``.
50  7. Implicit conversions of integral types to ``bool`` are replaced with
51     explicit comparisons to ``0``.
52
53Examples:
54  1. The ternary assignment ``bool b = (i < 0) ? true : false;`` has redundant
55     parentheses and becomes ``bool b = i < 0;``.
56
57  2. The conditional return ``if (!b) return false; return true;`` has an
58     implied double negation and becomes ``return b;``.
59
60  3. The conditional return ``if (i < 0) return false; return true;`` becomes
61     ``return i >= 0;``.
62
63     The conditional return ``if (i != 0) return false; return true;`` becomes
64     ``return i == 0;``.
65
66  4. The conditional return ``if (p) return true; return false;`` has an
67     implicit conversion of a pointer to ``bool`` and becomes
68     ``return p != nullptr;``.
69
70     The ternary assignment ``bool b = (i & 1) ? true : false;`` has an
71     implicit conversion of ``i & 1`` to ``bool`` and becomes
72     ``bool b = (i & 1) != 0;``.
73
74  5. The conditional return ``if (i & 1) return true; else return false;`` has
75     an implicit conversion of an integer quantity ``i & 1`` to ``bool`` and
76     becomes ``return (i & 1) != 0;``
77
78  6. Given ``struct X { explicit operator bool(); };``, and an instance ``x`` of
79     ``struct X``, the conditional return ``if (x) return true; return false;``
80     becomes ``return static_cast<bool>(x);``
81
82Options
83-------
84
85.. option:: IgnoreMacros
86
87   If `true`, ignore boolean expressions originating from expanded macros.
88   Default is `false`.
89
90.. option:: ChainedConditionalReturn
91
92   If `true`, conditional boolean return statements at the end of an
93   ``if/else if`` chain will be transformed. Default is `false`.
94
95.. option:: ChainedConditionalAssignment
96
97   If `true`, conditional boolean assignments at the end of an ``if/else
98   if`` chain will be transformed. Default is `false`.
99
100.. option:: SimplifyDeMorgan
101
102   If `true`, DeMorgan's Theorem will be applied to simplify negated
103   conjunctions and disjunctions.  Default is `true`.
104
105.. option:: SimplifyDeMorganRelaxed
106
107   If `true`, :option:`SimplifyDeMorgan` will also transform negated
108   conjunctions and disjunctions where there is no negation on either operand.
109   This option has no effect if :option:`SimplifyDeMorgan` is `false`.
110   Default is `false`.
111
112   When Enabled:
113
114   .. code-block::
115
116      bool X = !(A && B)
117      bool Y = !(A || B)
118
119   Would be transformed to:
120
121   .. code-block::
122
123      bool X = !A || !B
124      bool Y = !A && !B
125