Navigation



3.1 — Precedence and associativity

In order to properly evaluate an expression such as 4 + 2 * 3, we must understand both what the operators do, and the correct order to apply them. The order in which operators are evaluated in a compound expression is called operator precedence. Using normal mathematical precedence rules (which states that multiplication is resolved before addition), we know that the above expression should evaluate as 4 + (2 * 3) = 10.

In C++, all operators are assigned a level of precedence. Those with the highest precedence are evaluated first. You can see in the table below that multiplication and division (precedence level 5) have a higher precedence than addition and subtraction (precedence level 6). The compiler uses these levels to determine how to evaluate expressions it encounters.

If two operators with the same precedence level are adjacent to each other in an expression, the associativity rules tell the compiler whether to evaluate the operators from left to right or from right to left. For example, in the expression 3 * 4 / 2, the multiplication and division operators are both precedence level 5. Level 5 has an associativity of left to right, so the expression is resolved from left to right: (3 * 4) / 2 = 6.

Prec/Ass Operator Description Example
1 None ::
::
Global scope (unary)
Class scope (binary)
::g_nGlobalVar = 5;
Class::m_nMemberVar = 5;
2 L->R ()
()
()
[]
.
->
++
––
typeid
const_cast
dynamic_cast
reinterpret_cast
static_cast
Parenthesis
Function call
Implicit assignment
Array subscript
Member access from object
Member access from object ptr
Post-increment
Post-decrement
Run-time type information
Cast away const
Run-time type-checked cast
Cast one type to another
Compile-time type-checked cast
(x + y) * 2;
Add(x, y);
int nValue(5);
aValue[3] = 2;
cObject.m_nValue = 4;
pObject->m_nValue = 4;
nValue++;
nValue––;
typeid(cClass).name();
const_cast<int*>(pnConstValue);
dynamic_cast<Shape*>(pShape);
reinterpret_cast<Class2>(cClass1);
fValue = static_cast<float>(nValue);
3 R->L +
-
++
––
!
~
(type)
sizeof
&
*
new
new[]
delete
delete[]
Unary plus
Unary minus
Pre-increment
Pre-decrement
Logical NOT
Bitwise NOT
C-style cast
Size in bytes
Address of
Dereference
Dynamic memory allocation
Dynamic array allocation
Dynamic memory deletion
Dynamic array deletion
nValue = +5;M
nValue = -1;
++nValue;
––nValue;
if (!bValue)
nFlags = ~nFlags;
float fValue = (float)nValue;
sizeof(int);
address = &nValue;
nValue = *pnValue;
int *pnValue = new int;
int *panValue = new int[5];
delete pnValue;
delete[] panValue;
4 L->R ->*
.*
Member pointer selector
Member object selector
pObject->*pnValue = 24;
cObject->.*pnValue = 24;
5 L->R *
/
%
Multiplication
Division
Modulus
int nValue = 2 * 3;
float fValue = 5.0 / 2.0;
int nRemainder = 10 % 3;
6 L->R +
-
Addition
Subtraction
int nValue = 2 + 3;
int nValue = 2 – 3;
7 L->R <<
>>
Bitwise shift left
Bitwise shift right
int nFlags = 17 << 2;
int nFlags = 17 >> 2;
8 L->R <
<=
>
>=
Comparison less than
Comparison less than or equals
Comparison greater than
Comparison greater than or equals
if (x < y)
if (x <= y)
if (x > y)
if (x >= y)
9 L->R ==
!=
Equality
Inequality
if (x == y)
if (x != y)

10 L->R & Bitwise AND nFlags = nFlags & 17;
11 L->R ^ Bitwise XOR nFlags = nFlags ^ 17;
12 L->R | Bitwise OR nFlags = nFlags | 17;
13 L->R && Logical AND if (bValue1 && bValue2)
14 L->R || Logical OR if (bValue1 || bValue2)
15 L->R ?: Arithmetic if return (x < y) ? true : false;
16 R->L =
*=
/=
%=
+=
-=
<<=
>>=
&=
|=
^=
Assignment
Multiplication assignment
Division assignment
Modulus assignment
Addition assignment
Subtraction assignment
Bitwise shift left assignment
Bitwise shift right assignment
Logical AND assingment
Logical OR assignment
Logical XOR assignment
nValue = 5;
nValue *= 5;
fValue /= 5.0;
nValue %= 5;
nValue += 5;
nValue -= 5;
nFlags <<= 2;
nFlags >>= 2;
nFlags &= 17;
nFlags |= 17;
nFlags ^= 17;
17 L->R , Comma operator iii++, jjj++, kkk++;

A few operators you should already recognize: +, -, *, /, (), =, <, >, <=, and >=. These arithmetic and relational operators have the same meaning in C++ as they do in every-day usage.

However, unless you have experience with another programming language, it’s likely the majority of the operators in this table will be incomprehensible to you at this point in time. That’s expected at this point. We’ll cover many of them in this chapter, and the rest will be introduced as there is a need for them.

The above table is primarily meant to be a reference chart that you can refer back to in the future to resolve any precedence or associativity questions you have.

3.2 — Arithmetic operators
Index
2.10 — Comprehensive quiz

18 comments to 3.1 — Precedence and associativity

You must be logged in to post a comment.