C++ Operator Precedence


The following table lists the precedence and associativity of C++ operators. Operators are listed top to bottom, in descending precedence.

Precedence

Operator

Description

Associativity

1

​::​

​Scope resolution​

Left-to-right

2

​++​​​​--​

Suffix/postfix ​​increment and decrement​

type()​​​type{}​

​Functional cast​

​()​

​Function call​

​[]​

​Subscript​

​.​​​​->​

​Member access​

3

​++​​​​--​

Prefix ​​increment and decrement​

Right-to-left

​+​​​​-​

Unary ​​plus and minus​

​!​​​​~​

​Logical NOT​​​ and ​​bitwise NOT​

​(type)​

​C-style cast​

​*​

​Indirection​​ (dereference)

​&​

​Address-of​

​sizeof​

​Size-of​​​[note 1]

​new​​​​new[]​

​Dynamic memory allocation​

​delete​​​​delete[]​

​Dynamic memory deallocation​

4

​.*​​​​->*​

​Pointer-to-member​

Left-to-right

5

​*​​​​/​​​​%​

​Multiplication, division, and remainder​

6

​+​​​​-​

​Addition and subtraction​

7

​<<​​​​>>​

Bitwise ​​left shift and right shift​

8

​<​​​​<=​

For ​​relational operators​​ < and ≤ respectively

​>​​​​>=​

For ​​relational operators​​ > and ≥ respectively

9

​==​​​​!=​

For ​​relational operators​​ = and ≠ respectively

10

​&​

​Bitwise AND​

11

​^​

​Bitwise XOR​​ (exclusive or)

12

​|​

​Bitwise OR​​ (inclusive or)

13

​&&​

​Logical AND​

14

​||​

​Logical OR​

15

​?:​

​Ternary conditional​​​[note 2]

Right-to-left

​throw​

​throw operator​

​=​

​Direct assignment​​ (provided by default for C++ classes)

​+=​​​​-=​

​Compound assignment​​ by sum and difference

​*=​​​​/=​​​​%=​

​Compound assignment​​ by product, quotient, and remainder

​<<=​​​​>>=​

​Compound assignment​​ by bitwise left shift and right shift

​&=​​​​^=​​​​|=​

​Compound assignment​​ by bitwise AND, XOR, and OR

16

​,​

​Comma​

Left-to-right

  1. ​↑​​ The operand of

​sizeof​

  1. can't be a C-style type cast: the expression

​sizeof (int) * p​

  1. is unambiguously interpreted as

​(sizeof(int)) * p​

  1. , but not

​sizeof((int)*p)​

  1. .
  2. ​↑​​ The expression in the middle of the conditional operator (between

?

  1. and

:

  1. ) is parsed as if parenthesized: its precedence relative to

​?:​

When parsing an expression, an operator which is listed on some row of the table above with a precedence will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it with a lower precedence. For example, the expressions ​​std::cout​​​ << a & and *p++ are parsed as (​​std::cout​​​ << a) & and *(p++), and not as ​​std::cout​​ << (a & b) or (*p)++.

Operators that have the same precedence are bound to their arguments in the direction of their associativity. For example, the expression a = b = is parsed as a = (b = c), and not as (a = b) = because of right-to-left associativity of assignment, but a + b - is parsed (a + b) - and not a + (b - c)

Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left (delete ++*p is delete(++(*p))) and unary postfix operators always associate left-to-right (a[1][2]++ is ((a[1])[2])++). Note that the associativity is meaningful for member access operators, even though they are grouped with unary postfix operators: a.b++ is parsed (a.b)++ and not a.(b++))

Operator precedence is unaffected by ​​operator overloading​​.

Notes

Precedence and associativity are compile-time concepts and are independent from ​​order of evaluation​​, which is a runtime concept.

The standard itself doesn't specify precedence levels. They are derived from the grammar.

​const_cast​​​, ​​static_cast​​​, ​​dynamic_cast​​​, ​​reinterpret_cast​​​, ​​typeid​​​, ​​sizeof...​​​, ​​noexcept​​​ and ​​alignof​​ are not included since they are never ambiguous.

Some of the operators have ​​alternate spellings​​​ (e.g., and for ​​&&​​, or for ​​||​​, not for ​​!​​, etc.).Relative precedence of the ternary conditional and assignment operators differs between C and C++: in C, assignment is not allowed on the right-hand side of a ternary conditional operator, so e = a < d ? a++ : a =cannot be parsed. Many C compilers use a modified grammar where ​​?:​​ has higher precedence than ​​=​​, which parses that as e = ( ((a < d) ? (a++) : a) = d ) (which then fails to compile because ​​?:​​ is never lvalue in C and ​​=​​requires lvalue on the left). In C++, ​​?:​​ and ​​=​​ have equal precedence and group right-to-left, so that e = a < d ? a++ : a = parses as e = ((a < d) ? (a++) : (a = d)).

See also

Common operators

​assignment​

​increment
decrement​

​arithmetic​

​logical​

​comparison​

​member
access​

​other​

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>=

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >>

!a
a && b
a ||

a == b
a != b
a < b
a > b
a <= b
a >=

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

Special operators

​static_cast​​​ converts one type to another related type 

​​​dynamic_cast​​​ converts within inheritance hierarchies 

​​​const_cast​​​ adds or removes ​​cv​​​ qualifiers

​​​reinterpret_cast​​​ converts type to unrelated type

​​​C-style cast​​​ converts one type to another by a mix of ​​static_cast​​, ​​const_cast​​, and ​​reinterpret_cast​​ 

​​​new​​​ allocates memory

​​​delete​​​ deallocates memory

​​​sizeof​​​ queries the size of a type

​​​sizeof...​​​ queries the size of a ​​parameter pack​​​ (since C++11)

​​​typeid​​​ queries the type information of a type

​​​noexcept​​​ checks if an expression can throw an exception (since C++11)

​​​alignof​​ queries alignment requirements of a type (since C++11)