summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Foperator_precedence.html
blob: 385172743c9277599cdd31d6c83346b3383a66e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    <h1 id="firstHeading" class="firstHeading">C Operator Precedence</h1>            <p>The following table lists the precedence and associativity of C operators. Operators are listed top to bottom, in descending precedence.</p>
<table class="wikitable"> <tr> <th> Precedence </th> <th> Operator </th> <th> Description </th> <th> Associativity </th>
</tr> <tr> <th rowspan="6"> 1 </th> <td> <code>++</code> <code>--</code> </td> <td> Suffix/postfix increment and decrement </td> <td rowspan="6"> Left-to-right </td>
</tr> <tr> <td> <code>()</code> </td> <td> Function call </td>
</tr> <tr> <td> <code>[]</code> </td> <td> Array subscripting </td>
</tr> <tr> <td> <code>.</code> </td> <td> Structure and union member access </td>
</tr> <tr> <td> <code>-&gt;</code> </td> <td> Structure and union member access through pointer </td>
</tr> <tr> <td> <code>(<i>type</i>){<i>list</i>}</code> </td> <td> Compound literal<span class="t-mark-rev t-since-c99">(C99)</span> </td>
</tr> <tr> <th rowspan="8"> 2 </th> <td> <code>++</code> <code>--</code> </td> <td> Prefix increment and decrement<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[note 1]</a></sup> </td> <td rowspan="8"> Right-to-left </td>
</tr> <tr> <td> <code>+</code> <code>-</code> </td> <td> Unary plus and minus </td>
</tr> <tr> <td> <code>!</code> <code>~</code> </td> <td> Logical NOT and bitwise NOT </td>
</tr> <tr> <td> <code>(<i>type</i>)</code> </td> <td> Cast </td>
</tr> <tr> <td> <code>*</code> </td> <td> Indirection (dereference) </td>
</tr> <tr> <td> <code>&amp;</code> </td> <td> Address-of </td>
</tr> <tr> <td> <code>sizeof</code> </td> <td> Size-of<sup id="cite_ref-2" class="reference"><a href="#cite_note-2">[note 2]</a></sup> </td>
</tr> <tr> <td> <code>_Alignof</code> </td> <td> Alignment requirement<span class="t-mark-rev t-since-c11">(C11)</span> </td>
</tr> <tr> <th> 3 </th> <td> <code>*</code> <code>/</code> <code>%</code> </td> <td> Multiplication, division, and remainder </td> <td rowspan="11"> Left-to-right </td>
</tr> <tr> <th> 4 </th> <td> <code>+</code> <code>-</code> </td> <td> Addition and subtraction </td>
</tr> <tr> <th> 5 </th> <td> <code>&lt;&lt;</code> <code>&gt;&gt;</code> </td> <td> Bitwise left shift and right shift </td>
</tr> <tr> <th rowspan="2"> 6 </th> <td> <code>&lt;</code> <code>&lt;=</code> </td> <td> For relational operators &lt; and ≤ respectively </td>
</tr> <tr> <td> <code>&gt;</code> <code>&gt;=</code> </td> <td> For relational operators &gt; and ≥ respectively </td>
</tr> <tr> <th> 7 </th> <td> <code>==</code> <code>!=</code> </td> <td> For relational = and ≠ respectively </td>
</tr> <tr> <th> 8 </th> <td> <code>&amp;</code> </td> <td> Bitwise AND </td>
</tr> <tr> <th> 9 </th> <td> <code>^</code> </td> <td> Bitwise XOR (exclusive or) </td>
</tr> <tr> <th> 10 </th> <td> <code>|</code> </td> <td> Bitwise OR (inclusive or) </td>
</tr> <tr> <th> 11 </th> <td> <code>&amp;&amp;</code> </td> <td> Logical AND </td>
</tr> <tr> <th> 12 </th> <td> <code>||</code> </td> <td> Logical OR </td>
</tr> <tr> <th> 13 </th> <td> <code>?:</code> </td> <td> Ternary conditional<sup id="cite_ref-3" class="reference"><a href="#cite_note-3">[note 3]</a></sup> </td> <td rowspan="6"> Right-to-left </td>
</tr> <tr> <th rowspan="5"> 14<sup id="cite_ref-4" class="reference"><a href="#cite_note-4">[note 4]</a></sup> </th> <td> <code>=</code> </td> <td> Simple assignment </td>
</tr> <tr> <td> <code>+=</code> <code>-=</code> </td> <td> Assignment by sum and difference </td>
</tr> <tr> <td> <code>*=</code> <code>/=</code> <code>%=</code> </td> <td> Assignment by product, quotient, and remainder </td>
</tr> <tr> <td> <code>&lt;&lt;=</code> <code>&gt;&gt;=</code> </td> <td> Assignment by bitwise left shift and right shift </td>
</tr> <tr> <td> <code>&amp;=</code> <code>^=</code> <code>|=</code> </td> <td> Assignment by bitwise AND, XOR, and OR </td>
</tr> <tr> <th> 15 </th> <td> <code>,</code> </td> <td> Comma </td> <td> Left-to-right </td>
</tr>
</table> <ol class="references"> <li id="cite_note-1"> <span class="reference-text">The operand of prefix <code>++</code> and <code>--</code> can't be a type cast. This rule grammatically forbids some expressions that would be semantically invalid anyway. Some compilers ignore this rule and detect the invalidity semantically.</span> </li> <li id="cite_note-2"> <span class="reference-text">The operand of <code>sizeof</code> can't be a type cast: the expression <code>sizeof (int) * p</code> is unambiguously interpreted as <code>(sizeof(int)) * p</code>, but not <code>sizeof((int)*p)</code>.</span> </li> <li id="cite_note-3"> <span class="reference-text">The expression in the middle of the conditional operator (between <code>?</code> and <code>:</code>) is parsed as if parenthesized: its precedence relative to <code>?:</code> is ignored.</span> </li> <li id="cite_note-4"> <span class="reference-text">Assignment operators' left operands must be unary (level-2 non-cast) expressions. This rule grammatically forbids some expressions that would be semantically invalid anyway. Many compilers ignore this rule and detect the invalidity semantically. For example, <code>e = a &lt; d ? a++ : a = d</code> is an expression that cannot be parsed because of this rule. However, many compilers ignore this rule and parse it as <code>e = ( ((a &lt; d) ? (a++) : a) = d )</code>, and then give an error because it is semantically invalid.</span> </li> </ol> <p>When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression <code>*p++</code> is parsed as <code>*(p++)</code>, and not as <code>(*p)++</code>.</p>
<p>Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression <code>a=b=c</code> is parsed as <code>a=(b=c)</code>, and not as <code>(a=b)=c</code> because of right-to-left associativity.</p>
<h3 id="Notes"> Notes</h3> <p>Precedence and associativity are independent from <a href="eval_order" title="c/language/eval order">order of evaluation</a>.</p>
<p>The standard itself doesn't specify precedence levels. They are derived from the grammar.</p>
<p>In C++, the conditional operator has the same precedence as assignment operators, and prefix <code>++</code> and <code>--</code> and assignment operators don't have the restrictions about their operands.</p>
<p>Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left (<code>sizeof ++*p</code> is <code>sizeof(++(*p))</code>) and unary postfix operators always associate left-to-right (<code>a[1][2]++</code> is <code>((a[1])[2])++</code>). Note that the associativity is meaningful for member access operators, even though they are grouped with unary postfix operators: <code>a.b++</code> is parsed <code>(a.b)++</code> and not <code>a.(b++)</code>.</p>
<h3 id="References"> References</h3>  <ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul><li> A.2.1 Expressions </li></ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul><li> A.2.1 Expressions </li></ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul><li> A.2.1 Expressions </li></ul>
<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
<ul><li> A.1.2.1 Expressions </li></ul>
</ul>               <h3 id="See_also"> See also</h3> <p><a href="eval_order" title="c/language/eval order">Order of evaluation</a> of operator arguments at run time.</p>
<table class="wikitable"> <tr style="text-align:center"> <th colspan="7"> Common operators </th>
</tr> <tr style="text-align:center"> <td> <a href="operator_assignment" title="c/language/operator assignment"> assignment</a> </td> <td> <a href="operator_incdec" title="c/language/operator incdec"> increment<br>decrement</a> </td> <td> <a href="operator_arithmetic" title="c/language/operator arithmetic"> arithmetic</a> </td> <td> <a href="operator_logical" title="c/language/operator logical"> logical</a> </td> <td> <a href="operator_comparison" title="c/language/operator comparison"> comparison</a> </td> <td> <a href="operator_member_access" title="c/language/operator member access"> member<br>access</a> </td> <td> <a href="operator_other" title="c/language/operator other"> other</a> </td>
</tr> <tr style="text-align:center"> <td> <p><code>a = b a += b a -= b a *= b a /= b a %= b a &amp;= b a |= b a ^= b a &lt;&lt;= b a &gt;&gt;= b</code></p>
</td> <td> <p><code>++a --a a++ a--</code></p>
</td> <td> <p><code>+a -a a + b a - b a * b a / b a % b ~a a &amp; b a | b a ^ b a &lt;&lt; b a &gt;&gt; b</code></p>
</td> <td> <p><code>!a a &amp;&amp; b a || b</code></p>
</td> <td> <p><code>a == b a != b a &lt; b a &gt; b a &lt;= b a &gt;= b</code></p>
</td> <td> <p><code>a[b] *a &amp;a a-&gt;b a.b</code></p>
</td> <td> <p><code>a(...) a, b (type) a a ? b : c sizeof</code><br><br> <code>_Alignof</code><br><span class="t-mark-rev t-since-c11">(since C11)</span></p>
</td>
</tr> </table> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/operator_precedence" title="cpp/language/operator precedence">C++ documentation</a></span> for <span class=""><span>C++ operator precedence</span></span> </td>
</tr> </table>           <div class="_attribution">
  <p class="_attribution-p">
    &copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
    <a href="https://en.cppreference.com/w/c/language/operator_precedence" class="_attribution-link">https://en.cppreference.com/w/c/language/operator_precedence</a>
  </p>
</div>