Search

Admin

3.1 — Operator 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 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++, 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.

Thus, 4 + 2 * 3 evaluates as 4 + (2 * 3) because multiplication has a higher level of precedence than addition.

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.

Table of operators

Notes:

  • Precedence level 1 is the highest precedence level, and level 18 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)
Class scope (binary)
::name
class_name::member_name
2 L->R ()
()
()
type()
[]
.
->
++
––
typeid
const_cast
dynamic_cast
reinterpret_cast
static_cast
Parenthesis
Function call
Initialization
Value construction
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
(expression)
function_name(parameters)
type name(expression)
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)
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
+expression
-expression
++lvalue
––lvalue
!expression
~expression
(type)expression
sizeof(type) or sizeof(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 +
-
Addition
Subtraction
expression + expression
expression - expression
7 L->R <<
>>
Bitwise shift left
Bitwise shift right
expression << expression
expression >> expression
8 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
9 L->R ==
!=
Equality
Inequality
expression == expression
expression != expression
10 L->R & Bitwise AND expression & expression
11 L->R ^ Bitwise XOR expression ^ expression
12 L->R | Bitwise OR expression | expression
13 L->R && Logical AND expression && expression
14 L->R || Logical OR expression || expression
15 R->L ?: Conditional expression ? expression : expression
16 R->L =
*=
/=
%=
+=
-=
<<=
>>=
&=
|=
^=
Assignment
Multiplication assignment
Division assignment
Modulus assignment
Addition assignment
Subtraction assignment
Bitwise shift left assignment
Bitwise shift right assignment
Bitwise AND assignment
Bitwise OR assignment
Bitwise XOR assignment
lvalue = expression
lvalue *= expression
lvalue /= expression
lvalue %= expression
lvalue += expression
lvalue -= expression
lvalue <<= expression
lvalue >>= expression
lvalue &= expression
lvalue |= expression
lvalue ^= expression
17 R->L throw Throw expression throw expression
18 L->R , Comma operator expression, expression

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.

Quiz

1) You know from everyday mathematics that expressions inside of parenthesis 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 parenthesis. 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.

Hint: Use the pattern column in the table above to determine whether the operator is unary (has one operand) or binary (has two operands). Review section 1.5 -- A first look at operators if you need a refresher on what unary and binary operators are.

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;
b) x = y = z;
c) z *= ++y + 5;
d) a || b && c || d;

Solutions

1) Show Solution

3.2 -- Arithmetic operators
Index
2.10 -- Chapter 2 comprehensive quiz

25 comments to 3.1 — Operator precedence and associativity

  • Ole

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

  • 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.

  • 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 .

  • msk

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

  • 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.

  • 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…

  • Name (required)

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

  • 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.

  • 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.

  • techsavvy....aye

    Thanks a ton.

  • 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.

  • 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().

  • R4Z3R

    what is the difference between :

    which one is recommended ?

  • 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.

Leave a Comment

  

  

  

13 − five =

Put C++ code inside [code][/code] tags to use the syntax highlighter