C++ Operator Precedence and Associativity

C++ Operators Precedence

If there are multiple operators in a single expression, the operations are not evaluated simultaneously. Rather, operators with higher precedence have their operations evaluated first.

Let us consider an example:

int x = 5 - 17 * 6; 

Here, the multiplication operator * is of higher level precedence than the subtraction operator -. Hence, 17 * 6 is evaluated first.

As a result, the above expression is equivalent to

int x = 5 - (17 * 6);

If we wish to evaluate 5 - 17 first, then we must enclose them within parentheses:

int x = (5 - 17) * 6;

Example 1: Operators Precedence

#include <iostream>
using namespace std;

int main() {

  // evaluates 17 * 6 first
  int num1 = 5 - 17 * 6;

  // equivalent expression to num1
  int num2 = 5 - (17 * 6);

  // forcing compiler to evaluate 5 - 17 first
  int num3 = (5 - 17) * 6;

  cout << "num1 = " << num1 << endl;
  cout << "num2 = " << num2 << endl;
  cout << "num3 = " << num3 << endl;

  return 0;
}

Output

num1 = -97
num2 = -97
num3 = -72

Note: Because there are a lot of operators in C++ with multiple levels of precedence, it is highly recommended that we use parentheses to make our code more readable.


C++ Operators Precedence Table

The following table (taken from cppreference.com) shows the precedence of C++ operators. Precedence Level 1 signifies operators of highest priority, while Precedence Level 17 signifies operators of the lowest priority.

The property of associativity will be discussed shortly.

Precedence Operator Description Associativity
1 :: Scope Resolution Left to Right
2 a++
a--
type( )
type{ }
a( )
a[ ]
.
->
Suffix/postfix increment
Suffix/postfix decrement
Function cast
Function cast
Function call
Subscript
Member access from an object
Member access from object ptr
Left to Right
3 ++a
--a
+a
-a
!
~
(type)
*a
&a
sizeof
co_await
new new[ ]
delete delete[]
Prefix increment
Prefix decrement
Unary plus
Unary minus
Logical NOT
Bitwise NOT
C style cast
Indirection (dereference)
Address-of
Size-of
await-expression
Dynamic memory allocation
Dynamic memory deallocation
Right to Left
4 .*
->*
Member object selector
Member pointer selector
Left to Right
5 a * b
a / b
a % b
Multiplication
Division
Modulus
Left to Right
6 a + b
a - b
Addition
Subtraction
Left to Right
7 <<
>>
Bitwise left shift
Bitwise right shift
Left to Right
8 <=< Three-way comparison operator Left to Right
9 <
<=
>
>=
Less than
Less than or equal to
Greater than
Greater than or equal to
Left to Right
10 ==
!=
Equal to
Not equal to
Left to Right
11 & Bitwise AND Left to Right
12 ^ Bitwise XOR Left to Right
13 | Bitwise OR Left to Right
14 && Logical AND Left to Right
15 || Logical OR Left to Right
16 a ? b : c
throw
co_yield
=
+=
-=
*=
/=
%=
<<=
>>=
&=
^=
|=
Ternary Conditional
throw operator
yield expression (C++ 20)
Assignment
Addition Assignment
Subtraction Assignment
Multiplication Assignment
Division Assignment
Modulus Assignment
Bitwise Shift Left Assignment
Bitwise Shift Right Assignment
Bitwise AND Assignment
Bitwise XOR Assignment
Bitwise OR Assignment
Right to Left
17 , Comma operator Left to Right

C++ Operators Associativity

Operator associativity is the direction from which an expression is evaluated. For example,

int a = 1;
int b = 4;

// a will be 4
a = b;

Take a look at a = 4; statement. The associativity of the = operator is from right to left. Hence, the value of b is assigned to a, and not in the other direction.

Also, multiple operators can have the same level of precedence (as we can see from the above table). When multiple operators of the same precedence level are used in an expression, they are evaluated according to their associativity.

int a = 1;
int b = 4;
b += a -= 6;

Both operators += and -= operators have the same precedence. Since the associativity of these operators is from right to left, here is how the last statement is evaluated.

  • a -= 6 is evaluated first. Hence, a will be -5
  • Then, b += -5 will be evaluated. Hence, b will be -1

Example 2: Operators Associativity

#include <iostream>
using namespace std;

int main() {
  int a = 1;
  int b = 4;

// a -= 6 is evaluated first
  b += a -= 6;

  cout << "a = " << a << endl; ;
  cout << "b = " << b;
}

Output

a = -5
b = -1