This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 8.0.1 - Parentheses should be used to make the meaning of an expression appropriately explicit
Category: Advisory
Analysis: Decidable,Single Translation Unit
Amplification
The following table is used in the definition of this rule.
Description |
Operator or Operand |
Ranking |
Other |
Any operator or operand not listed below |
14 (high) |
Multiplicative |
* / %
|
13 |
Additive |
+ -
|
12 |
Bitwise shift |
<< >>
|
11 |
Relational |
< > <= >=
|
10 |
Equality |
== !=
|
9 |
Bitwise AND |
&
|
8 |
Bitwise XOR |
^
|
7 |
Bitwise OR |
|
|
6 |
Logical AND |
&&
|
5 |
Logical OR |
||
|
4 |
Conditional |
?:
|
3 |
Assignment |
= *= /= %= += -= <<= >>= &= ^= |=
|
2 |
Throw |
throw
|
1 |
Comma |
,
|
0 (low) |
The rankings used in this table are chosen to allow a concise description of the rule. They are not necessarily the same as those that might be
encountered in the C++ Standard’s descriptions of operator precedence.
Notes:
- Operators having alternative token representations (see [lex.digraph]) have the same ranking as their primary form.
- The additive row does not include unary plus and unary minus, which have rank 14.
An expression is appropriately explicit when:
- Its ranking is 0, 1, 2 or 14; or
- Each operand:
- Is parenthesized; or
- Has a ranking of 14; or
- Has ranking less than or equal to that of the expression.
Additionally, the operand to the sizeof operator should be parenthesized.
For the purposes of this rule, the ranking of an expression is the ranking of the element (operand or operator) at the root of the parse tree for
that expression. For a sub-expression, its ranking is that of the element at the "root" of the sub-tree.
For example, using the syntax and precedence rules from the C++ Standard, the parse tree for the non-compliant expression a << b +
c can be represented as:
<<
/ \
a +
/ \
b c
The element at the root of this parse tree is '<<', so the expression has ranking 11. The root of the sub-tree for b +
c is +, which has ranking 12.
Rationale
The C++ language has a comparatively large number of operators and their relative precedences are not intuitive. This can lead less experienced
developers to make mistakes. Using parentheses to make operator bindings explicit removes the possibility that the developer’s expectations are
incorrect. It also makes the original developer’s intention clear to reviewers or maintainers of the code.
It is recognized that overuse of parentheses can clutter the code and reduce its readability. However, too few parentheses can lead to unintuitive
code. This rule tries to achieve a reasonable compromise.
Note: this rule does not require the operands of a comma operator to be parenthesized, even though the result may not meet
developer expectation. However, use of the comma operator is not compliant with M23_105: MISRA C++ 2023 Rule 8.19.1.
x = a, b; // Parsed as ( x = a ), b
Example
The following examples show expressions with a unary or postfix operator whose operands are either primary-expressions or expressions
whose top-level operators have ranking 14:
a[ i ]->n; // Compliant - no need to write ( a[ i ] )->n
*p++; // Compliant - no need to write *( p++ )
sizeof x + y; // Non-compliant - write either sizeof ( x ) + y
// or sizeof ( x + y )
The following examples show expressions containing operators of the same ranking:
a + b - c + d; // Compliant
( a + b ) - ( c + d ); // Compliant - produces a different result
The following examples show a variety of mixed-operator expressions:
x = f ( a + b, c ); // Compliant - no need to write f ( ( a + b ), c )
x = a == b ? a : a - b; // Non-compliant - operands of conditional operator
// (ranking 3) are:
// == (ranking 9) needs parentheses
// a (ranking 14) does not need parentheses
// - (ranking 12) needs parentheses
x = ( a == b ) ? a : ( a - b ); // Compliant version of previous example
Note: the assignment operators in the previous two examples are compliant — the ranking of the assignment operator is less than 3,
so its operands do not need parentheses.
x = a << b + c; // Non-compliant - operands of << operator
// (ranking 11) are:
// a (ranking 14) does not need parentheses
// + (ranking 12) needs parentheses
a && b && c; // Compliant - all operators are the same.
a && b || c; // Non-compliant - || (ranking 4) has operand && (ranking 5)
a || b && c; // Non-compliant - || (ranking 4) has operand && (ranking 5)
a || b || c; // Compliant - all operators are the same
#if defined( A ) && defined( B ) || defined( C ) // Non-compliant
Copyright The MISRA Consortium Limited © 2023