Skip to content

Commit 6574f05

Browse files
added ES.87 about conditions in if-statements
isocpp#1006 and isocpp#1010
1 parent 1a3de0e commit 6574f05

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

CppCoreGuidelines.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9522,6 +9522,7 @@ Statement rules:
95229522
* [ES.84: Don't (try to) declare a local variable with no name](#Res-noname)
95239523
* [ES.85: Make empty statements visible](#Res-empty)
95249524
* [ES.86: Avoid modifying loop control variables inside the body of raw for-loops](#Res-loop-counter)
9525+
* [ES.87: Don't add redundant `==` or `!=` to conditions](#Res-if)
95259526

95269527
Arithmetic rules:
95279528

@@ -11211,6 +11212,70 @@ The loop control up front should enable correct reasoning about what is happenin
1121111212

1121211213
Flag variables that are potentially updated (have a non-`const` use) in both the loop control iteration-expression and the loop body.
1121311214

11215+
11216+
### <a name="es-if"></a>ES.87: Don't add redundant `==` or `!=` to conditions
11217+
11218+
##### Reason
11219+
11220+
Doing so avoids verbosity and eliminats some opportunities for mistakes.
11221+
Helps make style consistent and conventional.
11222+
11223+
##### Example
11224+
11225+
By definition, a condition in an `if`-statement, `while`-statement, or a `for`-statement selects between `true` and `false`.
11226+
A numeric value is compared to `0` and a pointer value to `nullptr`.
11227+
11228+
if (p) { ... } // means "if `p` is not `nullptr`, good
11229+
if (p!=0) { ... } // means "if `p` is not `nullptr`, redundant `!=0`; bad: don't use 0 for pointers
11230+
if (p!=nullptr) { ... } // means "if `p` is not `nullptr`, redundant `!=nullptr`, not recommended
11231+
11232+
Often, `if (p)` is read as "if `p` is valid" which is a direct expression of the programmers intent,
11233+
whereas `if (p!=nullptr)` would be a long-winded workaround.
11234+
11235+
##### Example
11236+
11237+
This rule is especially useful when a declaration is used as a condition
11238+
11239+
if (auto pc = dynamic_cast<Circle>(ps)) { ... } // execute is ps points to a kind of Circle, good
11240+
11241+
if (auto pc = dynamic_cast<Circle>(ps); pc!=nullptr) { ... } // not recommended
11242+
11243+
##### Example
11244+
11245+
Note that implicit conversions to bool are applied in conditions.
11246+
For example:
11247+
11248+
for (string s; cin>>s; ) v.push_back(s);
11249+
11250+
This invokes `istream`'s `operator bool()`.
11251+
11252+
##### Example, bad
11253+
11254+
It has been noted that
11255+
11256+
if(strcmp(p1,p2)) { ... } // are the two C-style strings equal? (mistake!)
11257+
11258+
is a common beginners error.
11259+
If you use C-style strings, you must know the `<cstring>` functions well.
11260+
Being verbose and writing
11261+
11262+
if(strcmp(p1,p2)!=0) { ... } // are the two C-style strings equal? (mistake!)
11263+
11264+
would not save you.
11265+
11266+
##### Note
11267+
11268+
The opposite condition is most easily expressed using a negation:
11269+
11270+
if (!p) { ... } // means "if `p` is`nullptr`, good
11271+
if (p==0) { ... } // means "if `p` is `nullptr`, redundant `!=0`; bad: don't use `0` for pointers
11272+
if (p==nullptr) { ... } // means "if `p` is `nullptr`, redundant `==nullptr`, not recommended
11273+
11274+
##### Enforcement
11275+
11276+
Easy, just check for redundant use of `!=` and `==` in conditions.
11277+
11278+
1121411279
## ES.expr: Expressions
1121511280

1121611281
Expressions manipulate values.

0 commit comments

Comments
 (0)