# 5.1 — Operator precedence and associativity

Chapter introduction

This chapter builds on top of the concepts from lesson 1.8 -- Introduction to literals and operators. A quick review follows:

In mathematics, an operation is a mathematical calculation involving zero or more input values (called operands) that produces a new value (called an output value). The specific operation to be performed is denoted by a construct (typically a symbol or pair of symbols) called an operator.

For example, as children we all learn that 2 + 3 equals 5. In this case, the literals 2 and 3 are the operands, and the symbol + is the operator that tells us to apply mathematical addition on the operands to produce the new value 5.

In this chapter, we’ll discuss topics related to operators, and explore many of the common operators that C++ supports.

Operator precedence

Now, let’s consider a more complicated expression, such as 4 + 2 * 3. In order to evaluate this expression, 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 determined by an operator’s precedence. Using normal mathematical precedence rules (which state that multiplication is resolved before addition), we know that the above expression should evaluate as 4 + (2 * 3) to produce the value 10.

In C++, when the compiler encounters an expression, it must similarly analyze the expression and determine how it should be evaluated. To assist with this, all operators are assigned a level of precedence. Operators with the highest level of precedence are evaluated first.

You can see in the table below that multiplication and division (precedence level 5) have more precedence than addition and subtraction (precedence level 6). Thus, 4 + 2 * 3 evaluates as 4 + (2 * 3) because multiplication has a higher level of precedence than addition.

Operator associativity

What happens if two operators in the same expression have the same precedence level? For example, in the expression 3 * 4 / 2, the multiplication and division operators are both precedence level 5. In this case, the compiler can’t rely upon precedence alone to determine how to evaluate the result.

If two operators with the same precedence level are adjacent to each other in an expression, the operator’s associativity tells the compiler whether to evaluate the operators from left to right or from right to left. The operators in precedence level 5 have an associativity of left to right, so the expression is resolved from left to right: (3 * 4) / 2 = 6.

Table of operators

The below 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.

Notes:

• Precedence level 1 is the highest precedence level, and level 17 is the lowest. Operators with a higher precedence level get evaluated first.
• L->R means left to right associativity.
• R->L means right to left associativity.
Prec/Ass Operator Description Pattern
1 None ::
::
Global scope (unary)
Namespace scope (binary)
::name
class_name::member_name
2 L->R ()
()
()
{}
type()
type{}
[]
.
->
++
––
typeid
const_cast
dynamic_cast
reinterpret_cast
static_cast
sizeof…
noexcept
alignof
Parentheses
Function call
Initialization
Uniform initialization (C++11)
Functional cast
Functional cast (C++11)
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
Get parameter pack size
Compile-time exception check
Get type alignment
(expression)
function_name(parameters)
type name(expression)
type name{expression}
new_type(expression)
new_type{expression}
pointer[expression]
object.member_name
object_pointer->member_name
lvalue++
lvalue––
typeid(type) or typeid(expression)
const_cast<type>(expression)
dynamic_cast<type>(expression)
reinterpret_cast<type>(expression)
static_cast<type>(expression)
sizeof…(expression)
noexcept(expression)
alignof(Type)
3 R->L +
-
++
––
!
~
(type)
sizeof
co_await
&
*
new
new[]
delete
delete[]
Unary plus
Unary minus
Pre-increment
Pre-decrement
Logical NOT
Bitwise NOT
C-style cast
Size in bytes
Await asynchronous call
Dereference
Dynamic memory allocation
Dynamic array allocation
Dynamic memory deletion
Dynamic array deletion
+expression
-expression
++lvalue
––lvalue
!expression
~expression
(new_type)expression
sizeof(type) or sizeof(expression)
co_await expression
&lvalue
*expression
new type
new type[expression]
delete pointer
delete[] pointer
4 L->R ->*
.*
Member pointer selector
Member object selector
object_pointer->*pointer_to_member
object.*pointer_to_member
5 L->R *
/
%
Multiplication
Division
Modulus
expression * expression
expression / expression
expression % expression
6 L->R +
-
Subtraction
expression + expression
expression - expression
7 L->R <<
>>
Bitwise shift left
Bitwise shift right
expression << expression
expression >> expression
8 L->R <=> Three-way comparison expresstion <=> expression
9 L->R <
<=
>
>=
Comparison less than
Comparison less than or equals
Comparison greater than
Comparison greater than or equals
expression < expression
expression <= expression
expression > expression
expression >= expression
10 L->R ==
!=
Equality
Inequality
expression == expression
expression != expression
11 L->R & Bitwise AND expression & expression
12 L->R ^ Bitwise XOR expression ^ expression
13 L->R | Bitwise OR expression | expression
14 L->R && Logical AND expression && expression
15 L->R || Logical OR expression || expression
16 R->L throw
co_yield
?:
=
*=
/=
%=
+=
-=
<<=
>>=
&=
|=
^=
Throw expression
Yield expression
Conditional
Assignment
Multiplication assignment
Division assignment
Modulus assignment
Subtraction assignment
Bitwise shift left assignment
Bitwise shift right assignment
Bitwise AND assignment
Bitwise OR assignment
Bitwise XOR assignment
throw expression
co_yield expression
expression ? expression : expression
lvalue = expression
lvalue *= expression
lvalue /= expression
lvalue %= expression
lvalue += expression
lvalue -= expression
lvalue <<= expression
lvalue >>= expression
lvalue &= expression
lvalue |= expression
lvalue ^= expression
17 L->R , Comma operator expression, expression

You should already recognize a few of these operators, such as +, -, *, /, (), and sizeof. However, unless you have experience with another programming language, the majority of the operators in this table will probably be incomprehensible to you right now. 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.

Q: Where's the exponent operator?

C++ doesn’t include an operator to do exponentiation (operator^ has a different function in C++). We discuss exponentiation more in lesson 5.3 -- Modulus and Exponentiation.

Parenthesization

In normal arithmetic, you learned that you can use parenthesis to change the order of application of operations. For example, we know that 4 + 2 * 3 evaluates as 4 + (2 * 3), but if you want it to evaluate as (4 + 2) * 3 instead, you can explicitly parenthesize the expression to make it evaluate the way you want. This works in C++ because parenthesis have one of the highest precedence levels, so parenthesis generally evaluate before whatever is inside them.

Now consider an expression like x && y || z. Does this evaluate as (x && y) || z or x && (y || z)? You could look up in the table and see that && takes precedence over ||. But there are so many operators and precedence levels that it’s hard to remember them all. In order to reduce mistakes and make your code easier to understand without referencing a precedence table, it’s a good idea to parenthesize any non-trivial compound expression, so it’s clear what your intent is.

Best practice

Use parenthesis to make it clear how an expression should evaluate, even if they are technically unnecessary.

Quiz time

Question #1

You know from everyday mathematics that expressions inside of parentheses get evaluated first. For example, in the expression `(2 + 3) * 4`, the `(2 + 3)` part is evaluated first.

For this exercise, you are given a set of expressions that have no parentheses. Using the operator precedence and associativity rules in the table above, add parentheses to each expression to make it clear how the compiler will evaluate the expression.

Show Hint

 Sample problem: x = 2 + 3 % 4 Binary operator % has higher precedence than operator + or operator =, so it gets evaluated first: x = 2 + (3 % 4) Binary operator + has a higher precedence than operator =, so it gets evaluated next: Final answer: x = (2 + (3 % 4)) We now no longer need the table above to understand how this expression will evaluate.

a) x = 3 + 4 + 5;

Show Solution

b) x = y = z;

Show Solution

c) z *= ++y + 5;

Show Solution

d) a || b && c || d;

Show Solution

 5.2 -- Arithmetic operators Index 4.x -- Chapter 4 summary and quiz

### 154 comments to 5.1 — Operator precedence and associativity

• functionLover

here is a recursive definition for pow, just for fun:

• Dear Teacher, please let me send above code working.

Regards.

• Turya

Hi Alex,
Can you please explain b) question in quiz? '=' is L-> R operator, so shouldn't it be (x=y)=z?

• Alex

Operator= is R->L. Maybe you're confusing operator= with operator==?

• Turya

thanks!

• Nyap

Is it worth remembering the different operator precedence levels and their associativity rules, or should you just be aware that precedence and associativity exist?

• Alex

You don't need to memorize these. For the most part, things work as expected, and the tutorials that cover these operators will generally point out when something might be non-intuitive in this regard.

New programmers tend to have the most issues with the precedence of || vs && (assuming they are the same, when && is higher), and when using * as a dereference operator when mixed with member access operators . or -> (. and -> take precedence over *).

• Sean

In one of your early examples of operator precedence, the grouping used by the compiler is irrelevant.

3 * 4 / 2 takes the form a * b / c, which = (a * b) / c = a * (b / c).

Your use of brackets shows the precedence used clearly, but a non-trivial example may be more illustrative to some.

Nice tutorials, by the way.

• Alex

I see what you're saying, but at this point we haven't covered what most of these operators actually do yet. So my pool to draw from for an example is somewhat limited.

A good alternate example would be:

3 * 4 % 3, which evaluates as (3 * 4) % 3, which equals 0 (whereas 3 * (4 % 3) equals 3). But I haven't covered what operator % does yet.

• Pierre

Could you explain in a bit more detail what the exponent function you propose does? I don't get the `if (exp & 1)` or the `exp >>= 1` and I don't think these operators have been covered yet?

Thanks

• Alex

This function implements exponentiation via the exponentiation by squaring method (it's just more optimized than the version shown on Wikipedia).

"if (exp & 1)" translates to "if exp is odd", and "exp >>=1" means "divide exp by 2".

• Patrick

Hi Alex,

should {} be added as part of level 2 in the Prec/Ass column of the table? Initialization  type name{expression} (C++11)

P.s. awesome site and look forward to quizes in all tutorial chapters down the road.

• Alex

• Elpidius

Hi Alex, in sub-chapter 3.4 — Sizeof, comma, and conditional operators, you mention that assignment has even lower precedence than the ?: operator. However I cannot see the assignment operator listed in the "Table of Operators". Could you please list it?

• Alex

Both the assignment operator and conditional operator are in precedence row 15. I've corrected the erroneous statement in lesson 3.4.

• Elpidius

Thank you.

• Grevozin

Using pow() for computing exponents of integers and straightforward casting is an unsafe method. String like this will probably output some numbers consisting of nines only:

http://codeforces.com/blog/entry/21844

• Alex

Yes, which is why I noted that it was only okay to do if you know the arguments to pow() are small.

• Grevozin

This is not an overflow problem: this string gives output like "1, 10, 99, 1000, 9999,...". The problem is precision of pow() can cause the result to be 10^2=99.9999999 and then floor rounding by static_cast makes the output 10^2=99 which is totally incorrect. This problem should be avoided by using rounding to the nearest integer rather than direct static_cast or by writing your own pow() for integers (this will also work faster).

• Alex

I see what you're getting at, and what you say is true. I've updated the article to provide an integer implementation for pow(). It's simpler than trying to deal with all the edge cases of the double version.

Hello... I don't understand the associativity of special operators, in my case, static_cast...! (I'm talking about when it's sitting alone, not with similar operators in the same statment) does left to right mean that it takes the type "int" and apply it to the expression rather than getting the expression first and then applying the type int? It's confusing :(

• Alex

The left to right is only applicable when mixed with operators at the same level of precedence.

But isn't it applied on operators sitting alone like the assignment operator? It's right to left, means it takes the rvalue and assigns it to lvalue...?! Or I'm missing something here...

• Alex

I'm not sure I understand what you're asking. Assignment is an operator with a lower precedence, so the static cast is resolved first, and then an assignment is made.

The L->R and R->L tell you which directions things resolve if multiple operators have the same precedence. For example, 3 + 4 - 5 resolves as (3 + 4) - 5. With operators of different precedence levels, the ones with more precedence go first.

That's not what I meant... I mean that the direction (rule) referred to by the associativity of an operator, well most of the times, makes sense if we apply that "rule" to a single operator sitting alone if it's binary, without having to exist more than once... I noticed this "theory", that my mind picked up, in some operators like the assignment one that I mentioned, the compiler would go from righ to left with respect to every operand as in

after it detects the two assignment operators it'd go for the rightmost assignment operator (that's what you mean, I guess), but what I mean is that after it aims at the rightmost operator, it also looks for the rightmost (in this case it's the only right) operand then assigns it to the left operand, like its associativity is how generally the operator operands the operands.

Another example would probably be the bitwise shift left (or right), it has left to right associativity, thus in

after the compiler detects the presence of the operator, it would look at its left operand and then adds the value of the right operand to it

I dunno how would you look at this (personally I found that my point became silly after explaining it xd), but for the sake of knowledge... Maybe D:

• Although nothing serious, the notes say «level 18 is the lowest», but the table lists only 17 levels, however.

• Alex

Thanks, fixed!

• Shiva

Hi Alex, there is something that I don’t understand. Please look at the following code:

As per the above table both pre- and post-increment ++ operators have higher precedence than the << operator. Then why, in the first case in the above code, does the value of y (which is initially 1) get printed before it is incremented? I thought y++ should be evaluated first and then sent to std::cout by the << operator and get printed. This happens in the second case, where the operator is pre-increment. Why is this so?

• Shiva

Okay I found the answer in the Comments section of Module '3.3 — Increment/decrement operators, and side effects'. If anyone has the same doubt, refer Alex's reply to zhiwei's question among the comments on that module. Hope this might be useful to someone. :)

And Alex, thanks for these great tutorials. They are awesome! :)

• Alex

This is due to the way y++ evaluates. Since post-increment has higher precedence than <<, it evaluates first. Variable y initially has the value of 1. y++ evaluates to the current value of y (1), and then y is incremented. That value of 1 is then sent to be printed, even though y has now been changed.

• fee

apah bein yee...!!!

• hussein

hello
the precedence and associativity table has one problem:
ternary conditional is put above assignment in precedence order while it is not. they should both be put at level 15.

• Alex

You are correct. This changed between C and C++, and much of the reference material out there is incorrect (including Microsoft's C++ precedence table for Visual Studio!). I've updated the table. Thanks for the tip.

• takise

Thanks a lot. Pre- is level 3 btw in table provided, but I got it now. My thinking was if + and ++ are both in level 3 and level 3 is R->L it should be z *= ((++(y + 5))) but lol at me now I see the difference in + in level 3 ( unary ) and + in level 6 ( addition ). All clear now :) Great tutorial!

• takise

Hi, Alex, I can't understand c) in your quiz. ++/-- are both in level 2 and level 3. What is the difference? I assumed that if one in level 2 is called post- and one in level 3 is called pre- it matters on which side of operator they are. But in solution is z *= ((++y) + 5) so it seems ++y is level 2. How is it? Can you explain it little more?

• Alex

Yes, you are correct on all counts. pre is ++y, and post is y++. So in the quiz, we're looking at the pre version (++y) which is level 2.

• Mr D

Is it considered acceptable to use parenthesis often when in doubt about this issue, or would the purists poo-poo it and say it should be done without parenthesis and according to the rules in the above table? I, for one, doubt i'll ever memorize all that stuff!

• Alex

You can never have too many parenthesis in my opinion. Parenthesis make it clear what your intent is, and reduce precedence mistakes. Use them liberally!

• Hello,
I encountered a really strange thing with ++ and -- operators!
look at this snipped :

I expected that the result (result of m) of above code should be 10 (even when I compiled it in the php the result was 10) but in C++ the result was 9!
how is that possible!?
--------
an other question >

result(m) of following code in code::blocks : 19
result(m) of following code in borland C++ : 20

How is that possible!?

• Alex

This kind of inconsistency usually results from compilers evaluating things in a different order. The C++ specification doesn't specify the order that parameters should be evaluated, for example.

Generally speaking, in C++ you should never use a variable that has a side effect applied to it more than once in a given expression. Doing so is asking for trouble.

• Thank Info

• R4Z3R

what is the difference between :

which one is recommended ?

• Alex

int(myChar) is a C-style cast, and is not recommended in C++.
static_cast(myChar) is a C++-style static cast, and should be preferred in C++.

This is covered in lesson 4.4a -- Explicit type conversion (casting).

• Darren

Just to be pedantic but

is called a functional cast. A C-style cast would be

. However both use the same underlying mechanism to re-cast a variable; essentially C++ replaces the C-style or functional cast with a static_cast.

• Alex

Thanks, I've updated the article.

• Alex

It's totally acceptable.

My personal rule of thumb is that if the exponent is both an integer and 3 or less, I just do the multiplication by hand (it's easy enough to understand, and it saves me from having to #include the math header. If the exponent is 4 or more, or a floating point number, then I'll favor pow().

• Smokeycow

I found the pow() function interesting so incorporated it into the quiz from the previous lesson. You can see where I changed "* seconds * seconds" to the pow() function. My question is, is this considered acceptable and/or recommended use? Thanks v much.

• techsavvy....aye

Thanks a ton.

• techsavvy....aye

hi!Alex.
I wanted to know if it is necessary to learn the entire table for the correct sequence of these operators. Or there are some specific operators needed for daily programming.
Thank you.

• Alex

It's not really necessary to memorize all of the precedence levels, as most of them are pretty intuitive, and you can always look them up if something isn't working like it should. If you have any doubts, you can always disambiguate using parenthesis.

• Lyle

If you try to disambiguate with parenthesis, you'll get a compiler error.
If you do it with parentheses, you'll have pairs ;)

Great tutorials ! :)

• Alex

I didn't realize there was a difference. Thanks for enlightening me. :)

• Abdelkarim

hi Alex! good job keep it up (y)
i have a question, i'm wondering! is those tutorials are all about console programs?!
Thanks!

• Alex

Yes.

It's possible to create other kinds of applications in C++, such as windowed applications or graphical applications, but I don't cover those here, as doing so requires operating system specific functionality or add-ons.

• Abdelkarim

For someone who wants to learn GUI programming, is it worth it to continue with all those tutorials or should i start over with maybe other tutorials or books ...!

• Alex

Much of the GUI stuff builds on the fundamentals you'll learn here. If you finish these tutorials, you'll have a great foundation for anything you want to do later.

• Name (required)

Hey I have a question :)
What does the % operator do?

• Alex

Returns the remainder in an integer division. For example: 9 % 4 = 1 (9 / 4 = 2 remainder 1, so 9 % 4 = 1).

This is discussed in section 3.2 -- arithmetic operators.

• Kirill

Hi there, Alex!

Am I getting right that "+" operator (#6 Table) would be evaluated before "*" operator (#5 in Table) due to precedence level?

But mathematically "*" should be done first...

• Alex

No, operator* is evaluated before operator+. I'll try to make this more clear in the table.

• John

"In C++, all operators are assigned a level of precedence. Those with the highest precedence are evaluated first."

So, + [Addition 6 L->R] is evaluated before * [Multiplication 5 L-> R] ?

• Alex

No.

> Precedence level 1 is the highest precedence level, and level 17 is the lowest. Operators with a higher precedence level get evaluated first.

• Jonathan

Hello Alex,

Thank you for this very well made tutorial.

I'd like to suggest you to put 3.2 (arithmetic operators) before 3.1 (operator precedence and associativity), I think it will be easier to understand the quizz as unary arithmetic operators (+x and -x) has higher precedence than binary operators (x + y and x - y) which make this a bit confusing.

• msk

The quiz is really unclear in this one. I don't understand even a bit of it.

• Alex

I've updated the quiz question and answer to try and make it more comprehensible. Let me know if it makes more sense now.

• Wintur

Hey Alex,

I cannot seem to find the exponent operator, ^. Am I missing it, or was it not included.

Thanks
Wintur

• Alex

Strangely enough, C++ does not include an exponent operator. You have to use the pow() function.

pow(base, exponent) will return the results of baseexponent. To access the pow() function, you need to #include .

• Jim

Sorry to correct you, but you left out what header to include here! If I remember right it is #include <cmath> ,but I could be wrong.

• Alex

Yes, pow() lives in the <cmath> header.

• John

just a suggestion; if you could make the chart in to an image file as well so people could save it and pull it up at any time it might be easier for referencing in the future.

• Ole

Just a suggestion towards readability and clarity. The R->L and L->R could maybe be changed into R -> L and R <- L ?

• Happilicious

How about just make an arrow ->(going right) or <-(going left)? Makes it much easier to read in my opinion :)