Skip to content

Commit 60f2770

Browse files
committed
doc
1 parent cc71140 commit 60f2770

1 file changed

Lines changed: 39 additions & 35 deletions

File tree

man/checkers/knownConditionTrueFalse.md

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,66 @@
11
# knownConditionTrueFalse
22

33
**Message**: Condition 'x==5' is always true<br/>
4-
**Category**: Correctness<br/>
4+
**Category**: Code cleanup<br/>
55
**Severity**: Style<br/>
66
**Language**: C/C++
77

88
## Description
99

10-
cppcheck can already work out this condition's value from what it knows about the variables involved,
11-
so the condition is always true or always false.
10+
A condition is always true or always false.
1211

13-
## Motivation
12+
Note: a warning is not written for obvious cases like `if (false)`.
13+
14+
If a condition is always true then technically the condition is redundant. It
15+
can be removed so that the conditional code will be unconditionally executed.
16+
This reduces complexity.
17+
18+
If a condition is always false then the conditional code is unreachable and can
19+
be removed.
20+
21+
It is however also possible that the intended check never actually happens and
22+
a real bug (a wrong comparison, a typo'd variable, a value that was supposed to
23+
vary but doesn't) slips through unnoticed.
1424

15-
A condition that's always true or always false isn't testing anything - at best it's confusing,
16-
leftover, or dead code; at worst, it means the intended check never actually happens and a real bug (a
17-
wrong comparison, a typo'd variable, a value that was supposed to vary but doesn't) slips through
18-
unnoticed.
25+
## Motivation
1926

20-
This check may need `--check-level=exhaustive` to see every case.
27+
The condition may be invariant (always true or always false) by mistake,
28+
otherwise it is possible to cleanup redundant code to reduce complexity.
2129

2230
## How to fix
2331

24-
Before:
32+
Before (condition is always true):
2533
```cpp
2634
void f() {
2735
int x = 5;
28-
if (x == 5) {} // <- always true
36+
if (x == 5) { // <- always true
37+
dostuff();
38+
}
39+
}
40+
```
41+
42+
After: The condition is technically redundant, this code is logically the same.
43+
```cpp
44+
void f() {
45+
dostuff();
2946
}
3047
```
3148

32-
After: use the real variable instead of a fixed value, or remove the redundant check.
49+
Before (condition is always false):
3350
```cpp
34-
void f(int x) {
35-
if (x == 5) {}
51+
void f() {
52+
int x = 5;
53+
if (x < 3) { // <- always false
54+
dostuff();
55+
}
3656
}
3757
```
3858

39-
## False positives to be aware of
40-
41-
- **This check does not account for a member value changing through a call that reaches it indirectly**
42-
(for example, through a container of pointers the function iterates over). A member read before such
43-
a call can be wrongly assumed to still hold the same value afterwards:
44-
```cpp
45-
#include <map>
46-
#include <string>
47-
struct S { int i; };
48-
struct T {
49-
std::map<std::string, S*> m;
50-
S* get(const std::string& s) { return m[s]; }
51-
void modify() { for (const auto& e : m) e.second->i = 0; }
52-
};
53-
void f(T& t) {
54-
const S* p = t.get("abc");
55-
const int o = p->i;
56-
t.modify(); // this can change p->i
57-
if (p->i == o) {} // wrongly reported as always true
58-
}
59-
```
59+
After: The conditional code is unreachable, this code is logically the same.
60+
```cpp
61+
void f() {
62+
}
63+
```
6064

6165
## Related checkers
6266

0 commit comments

Comments
 (0)