{{Short description|none}} {{Use American English|date = March 2019}} {{Use dmy dates|date=December 2019}} This is a list of operators in the C and C++ programming languages.
All listed operators are in C++ and lacking indication otherwise, in C as well. Some tables include a "In C" column that indicates whether an operator is also in C. Note that C does not support operator overloading.
When not overloaded, for the operators <code>&&</code>, <code>||</code>, and <code>,</code> (the comma operator), there is a sequence point after the evaluation of the first operand.
Most of the operators available in C and C++ are also available in other C-family languages such as C#, D, Java, Perl, and PHP with the same precedence, associativity, and semantics.
Many operators specified by a sequence of symbols are commonly referred to by a name that consists of the name of each symbol. For example, <code>+=</code> and <code>-=</code> are often called "plus equal(s)" and "minus equal(s)", instead of the more verbose "assignment by addition" and "assignment by subtraction".
==Operators== In the following tables, lower case letters such as <code>a</code> and <code>b</code> represent literal values, object/variable names, or l-values, as appropriate. <code>R</code>, <code>S</code> and <code>T</code> stand for a data type, and <code>K</code> for a class or enumeration type. Some operators have alternative spellings using digraphs and trigraphs or operator synonyms.
===Arithmetic===
C and C++ have the same arithmetic operators and all can be overloaded in C++.
{| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | Addition | align="center" | {{nowrap| 1=<code>a '''+''' b</code>}} | {{cpp|1=R K::operator +(S b);}} | {{cpp|1=R operator +(K a, S b);}} |- | {{rh}} colspan="2" | Subtraction | align="center" | <code>a '''-''' b</code> | {{cpp|1=R K::operator -(S b);}} | {{cpp|1=R operator -(K a, S b);}} |- | {{rh}} colspan="2" | Unary plus; integer promotion |align="center" | <code>'''+'''a</code> | {{cpp|1=R K::operator +();}} | {{cpp|1=R operator +(K a);}} |- | {{rh}} colspan="2" | Unary minus; additive inverse | align="center" | <code>'''-'''a</code> | {{cpp|1=R K::operator -();}} | {{cpp|1=R operator -(K a);}} |- | {{rh}} colspan="2" | Multiplication | align="center" | <code>a '''*''' b</code> | {{cpp|1=R K::operator *(S b);}} | {{cpp|1=R operator *(K a, S b);}} |- | {{rh}} colspan="2" | Division | align="center" | <code>a '''/''' b</code> | {{cpp|1=R K::operator /(S b);}} | {{cpp|1=R operator /(K a, S b);}} |- | {{rh}} colspan="2" | Modulo<ref name="modulo" group="lower-alpha" /> | align="center" | <code>a '''%''' b</code> | {{cpp|1=R K::operator %(S b);}} | {{cpp|1=R operator %(K a, S b);}} |- | {{rh}} colspan="2" | Prefix increment | align="center" | <code>'''++'''a</code> | {{cpp|1=R& K::operator ++();}} | {{cpp|1=R& operator ++(K& a);}} |- | {{rh}} colspan="2" | Postfix increment | align="center" | <code>a'''++'''</code> | {{cpp|1=R K::operator ++(int);}}{{efn|name=dummy-int|The {{cpp|int}} is a dummy parameter to differentiate between prefix and postfix.}} | {{cpp|1=R operator ++(K& a, int);}}{{efn|name=dummy-int}} |- | {{rh}} colspan="2" | Prefix decrement | align="center" | <code>'''--'''a</code> | {{cpp|1=R& K::operator --();}} | {{cpp|1=R& operator --(K& a);}} |- | {{rh}} colspan="2" | Postfix decrement | align="center" | <code>a'''--'''</code> | {{cpp|1=R K::operator --(int);}}{{efn|name=dummy-int}} | {{cpp|1=R operator --(K& a, int);}}{{efn|name=dummy-int}} |}
===Relational===
All relational (comparison) operators can be overloaded in C++. Since C++20, the inequality operator is automatically generated if <code>operator==</code> is defined and all four relational operators are automatically generated if <code>operator<=></code> is defined.<ref>{{cite web|url=https://en.cppreference.com/w/cpp/language/operators#Comparison_operators|title=Operator overloading§Comparison operators|website=cppreference.com}}</ref>
{| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! rowspan="2" | In C ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | Equal to | align="center" | <code>a '''==''' b</code> | {{yes}} | {{cpp|1=bool K::operator ==(S const& b) const;}} | {{cpp|1=bool operator ==(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Not equal to | style="text-align:center;" | <code>a '''!=''' b</code> || {{yes}} | {{cpp|1=bool K::operator !=(S const& b) const;}} | {{cpp|1=bool operator !=(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Greater than | style="text-align:center;" | <code>a '''>''' b</code> || {{yes}} | {{cpp|1=bool K::operator >(S const& b) const;}} | {{cpp|1=bool operator >(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Less than | style="text-align:center;" | <code>a '''<''' b</code> || {{yes}} | {{cpp|1=bool K::operator <(S const& b) const;}} | {{cpp|1=bool operator <(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Greater than or equal to | style="text-align:center;" | <code>a '''>=''' b</code> || {{yes}} | {{cpp|1=bool K::operator >=(S const& b) const;}} | {{cpp|1=bool operator >=(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Less than or equal to | style="text-align:center;" | <code>a '''<=''' b</code> || {{yes}} | {{cpp|1=bool K::operator <=(S const& b) const;}} | {{cpp|1=bool operator <=(K const& a, S const& b);}} |- | {{rh}} colspan="2" | Three-way comparison<ref name="threewaycomparison" group="lower-alpha"/>{{efn|Possible return types: <code>std::weak_ordering</code>, <code>std::strong_ordering</code> and <code>std::partial_ordering</code> to which they all are convertible to.}} | style="text-align:center;" | <code>a '''<=>''' b</code> || {{no}} | {{cpp|1=auto K::operator <=>(const S &b);}} | {{cpp|1=auto operator <=>(const K &a, const S &b);}} |}
===Logical===
C and C++ have the same logical operators and all can be overloaded in C++.
Note that overloading logical ''AND'' and ''OR'' is discouraged, because as overloaded operators they always evaluate both operands instead of providing the normal semantics of short-circuit evaluation.<ref>{{Cite web|url=https://isocpp.org/wiki/faq/operator-overloading|title=Standard C++}}</ref>
{| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | NOT | align="center" | <code>'''!'''a</code> | {{cpp|1=bool K::operator !();}} | {{cpp|1=bool operator !(K a);}} |- | {{rh}} colspan="2" | AND | style="text-align:center;" | <code>a '''&&''' b</code> | {{cpp|1=bool K::operator &&(S b);}} | {{cpp|1=bool operator &&(K a, S b);}} |- | {{rh}} colspan="2" | OR | style="text-align:center;" | <code>a '''<nowiki>||</nowiki>''' b</code> | {{code|1=bool K::operator {{!!}}(S b);|lang=cpp}} | {{code|1=bool operator {{!!}}(K a, S b);|lang=cpp}} |}
===Bitwise===
C and C++ have the same bitwise operators and all can be overloaded in C++.
{| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | NOT | align="center" | <code>'''~'''a</code><br/> | {{cpp|1=R K::operator ~();}} | {{cpp|1=R operator ~(K a);}} |- | {{rh}} colspan="2" | AND | style="text-align:center;" | <code>a '''&''' b</code> | {{cpp|1=R K::operator &(S b);}} | {{cpp|1=R operator &(K a, S b);}} |- | {{rh}} colspan="2" | OR | style="text-align:center;" | <code>a '''<nowiki>|</nowiki>''' b</code> | {{cpp|1=R K::operator {{!}}(S b);|lang=cpp}} | {{cpp|1=R operator {{!}}(K a, S b);|lang=cpp}} |- | {{rh}} colspan="2" | XOR | style="text-align:center;" | <code>a '''^''' b</code> | {{cpp|1=R K::operator ^(S b);}} | {{cpp|1=R operator ^(K a, S b);}} |- | {{rh}} colspan="2" | Shift left<ref name="bitshift" group="lower-alpha" /> | style="text-align:center;" | <code>a '''<<''' b</code> | {{cpp|1=R K::operator <<(S b);}} | {{cpp|1=R operator <<(K a, S b);}} |- | {{rh}} colspan="2" | Shift right<ref name="bitshift" group="lower-alpha" />{{Refn | Operation="rightbitshift" | group="lower-alpha" | According to the C99 standard, the right shift of a negative number is implementation defined. Most implementations, e.g., the GCC,<ref name="Integers">{{Citation | contribution = Integers implementation | url = //gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Integers-implementation.html#Integers-implementation | title = GCC 4.3.3 | publisher = GNU}}.</ref> use an arithmetic shift (i.e., sign extension), but a logical shift is possible.}} | style="text-align:center;" | <code>a '''>>''' b</code> | {{cpp|1=R K::operator >>(S b);}} | {{cpp|1=R operator >>(K a, S b);}} |}
===Assignment===
C and C++ have the same assignment operators and all can be overloaded in C++.
For the combination operators, <code>a ⊚= b</code> (where <code>⊚</code> represents an operation) is equivalent to <code>a = a ⊚ b</code>, except that <code>a</code> is evaluated only once.
{| class="wikitable" style="width:100%" ! rowspan="2" | Operation ! rowspan="2" | Syntax ! colspan="2" | C++ prototype |- ! in class K ! outside class |- ! {{rh}} | Assignment | style="text-align:center;" | {{nowrap| 1=<code>a '''=''' b</code>}} | {{cpp|1=R& K::operator =(S b);}} | {{n/a}} |- ! {{rh}} | Addition combination | align="center" | <code>a '''+=''' b</code> | {{cpp|1=R& K::operator +=(S b);}} | {{cpp|1=R& operator +=(K& a, S b);}} |- ! {{rh}} | Subtraction combination | style="text-align:center;" | <code>a '''-=''' b</code> | {{cpp|1=R& K::operator -=(S b);}} | {{cpp|1=R& operator -=(K& a, S b);}} |- ! {{rh}} | Multiplication combination | style="text-align:center;" | <code>a '''*=''' b</code> | {{cpp|1=R& K::operator *=(S b);}} | {{cpp|1=R& operator *=(K& a, S b);}} |- ! {{rh}} | Division combination | style="text-align:center;" | <code>a '''/=''' b</code> | {{cpp|1=R& K::operator /=(S b);}} | {{cpp|1=R& operator /=(K& a, S b);}} |- ! {{rh}} | Modulo combination | style="text-align:center;" | <code>a '''%=''' b</code> | {{cpp|1=R& K::operator %=(S b);}} | {{cpp|1=R& operator %=(K& a, S b);}} |- ! {{rh}} | Bitwise AND combination | style="text-align:center;" | <code>a '''&=''' b</code> | {{cpp|1=R& K::operator &=(S b);}} | {{cpp|1=R& operator &=(K& a, S b);}} |- ! {{rh}} | Bitwise OR combination | style="text-align:center;" | <code>a '''<nowiki>|</nowiki>=''' b</code> | {{cpp|1=R& K::operator {{!}}=(S b);|lang=cpp}} | {{cpp|1=R& operator {{!}}=(K& a, S b);|lang=cpp}} |- ! {{rh}} | Bitwise XOR combination | style="text-align:center;" | <code>a '''^=''' b</code> | {{cpp|1=R& K::operator ^=(S b);}} | {{cpp|1=R& operator ^=(K& a, S b);}} |- ! {{rh}} | Bitwise left shift combination | style="text-align:center;" | <code>a '''<<=''' b</code> | {{cpp|1=R& K::operator <<=(S b);}} | {{cpp|1=R& operator <<=(K& a, S b);}} |- ! {{rh}} | Bitwise right shift combination{{Refn | name="rightbitshift" | group="lower-alpha" | According to the C99 standard, the right shift of a negative number is implementation defined. Most implementations, e.g., the GCC,<ref name="Integers">{{Citation | contribution = Integers implementation | url = //gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Integers-implementation.html#Integers-implementation | title = GCC 4.3.3 | publisher = GNU}}.</ref> use an arithmetic shift (i.e., sign extension), but a logical shift is possible.}} | style="text-align:center;" | <code>a '''>>=''' b</code> | {{cpp|1=R& K::operator >>=(S b);}} | {{cpp|1=R& operator >>=(K& a, S b);}} |}
===Member and pointer=== {| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! rowspan="2" | Can overload ! rowspan="2" | In C ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | Subscript | align="center" | <code>a'''['''b''']'''</code><code>a'''<:'''b''':>'''</code><ref>{{Cite web |title=ISO/IEC 9899:1999 specification, TC3 |url=https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf#%5B%7B%22num%22%3A148%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C-27%2C816%2Cnull%5D |at=p. 64, § 6.4.6 ''Ponctuators'' para. 3}}</ref> | {{yes}} | {{yes}} | {{cpp|1=R& K::operator [](S b);}}<br/>{{cpp|1=R& K::operator [](S b, ...);}}<ref name="sinceCXX23" group="lower-alpha" /> | {{n/a}} |- | {{rh}} colspan="2" | Indirection <br>{{small|(object pointed to by ''a'')}} | style="text-align:center;" | <code>'''*'''a</code> || {{yes}} || {{yes}} | {{cpp|1=R& K::operator *();}} | {{cpp|1=R& operator *(K a);}} |- | {{rh}} colspan="2" | Address-of <br>{{small|(address of ''a'')}} | style="text-align:center;" | <code>'''&'''a</code> || {{yes}}<ref name="addressof2" group="lower-alpha"/> || {{yes}} | {{cpp|1=R* K::operator &();}} | {{cpp|1=R* operator &(K a);}} |- | {{rh}} colspan="2" | Structure dereference <br>{{small|(member ''b'' of object pointed to by ''a'')}} | style="text-align:center;" | <code>a'''->'''b</code> || {{yes}} || {{yes}} | {{cpp|1=R* K::operator ->();}}<ref name="arrowptr" group="lower-alpha" /><br /> | {{n/a}} |- | {{rh}} colspan="2" | Structure reference <br>{{small|(member ''b'' of object ''a'')}} | style="text-align:center;" | <code>a'''.'''b</code> || {{no}} || {{yes}} | {{rh}} colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Member selected by pointer-to-member ''b'' of object pointed to by ''a''<ref name="arrowstar" group="lower-alpha" /> | style="text-align:center;" | <code>a'''->*'''b</code> || {{yes}} || {{no}} | {{cpp|1=R& K::operator ->*(S b);}} | {{cpp|1=R& operator ->*(K a, S b);}} |- | {{rh}} colspan="2" | Member of object ''a'' selected by pointer-to-member ''b'' | style="text-align:center;" | <code>a'''.*'''b</code> || {{no}} || {{no}} | {{rh}} colspan="2" {{n/a}} |}
===Other=== {| class="wikitable" style="width:100%" ! colspan="2" rowspan="2" | Operation ! rowspan="2" | Syntax ! rowspan="2" | Can overload ! rowspan="2" | In C ! colspan="2" | C++ prototype |- ! in class K ! outside class |- | {{rh}} colspan="2" | Function call | align="center" | <code>a'''('''a1, a2''')'''</code> | {{yes}} | {{yes}} | {{cpp|1=R K::operator ()(S a, T b, ...);}}<!--'operator' shows as blue even though other prototypes shows it as green; seems to be a bug in the cpp template; unknown how to workaround.--> | {{n/a}} |- | {{rh}} colspan="2" | Comma | style="text-align:center;" | <code>a''',''' b</code> || {{yes}} || {{yes}} | {{cpp|1=R K::operator ,(S b);}} | {{cpp|1=R operator ,(K a, S b);}} |- | {{rh}} colspan="2" | Ternary conditional | style="text-align:center;" | <code>a '''?''' b ''':''' c</code> || {{no}} || {{yes}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Scope resolution | style="text-align:center;" | <code>a'''::'''b</code><ref name="scopal" group="lower-alpha" /> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | User-defined literals<ref name="ud-literal" group="lower-alpha" /><ref name="sinceCXX11" group="lower-alpha" /> | style="text-align: center;" | <code><nowiki>"a"_b</nowiki></code> || {{yes}} || {{no}} | {{n/a}} | {{cpp|1=R operator "" _b(T a)}} |- | {{rh}} colspan="2" | Sizeof | style="text-align:center;" | <code>'''sizeof''' a</code><ref name="sizeof" group="lower-alpha" /><br /><code>'''sizeof''' (R)</code> || {{no}} || {{yes}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Size of parameter pack<ref name="sinceCXX11" group="lower-alpha" /> | style="text-align:center;" | <code>'''sizeof...'''(Args)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Alignof<ref name="sinceCXX11" group="lower-alpha" /> | style="text-align:center;" | <code>'''alignof'''(R)</code> <br> or <code>'''_Alignof'''(R)</code><ref name="alignof" group="lower-alpha"/> || {{no}} || {{yes}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Typeof<ref name="typeof" group="lower-alpha" /> | style="text-align:center;" | <code>'''typeof'''(a)</code><br/><code>'''typeof'''(R)</code><br/><code>'''typeof_unqual'''(a)</code><br/><code>'''typeof_unqual'''(R)</code> || {{n/a}} || {{yes}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Decltype<ref name="sinceCXX11" group="lower-alpha" /> | style="text-align:center;" | <code>'''decltype'''(a)</code><br/><code>'''decltype'''(R)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Type identification | style="text-align:center;" | <code>'''typeid'''(a)</code><br><code>'''typeid'''(R)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Conversion<br>{{small|(C-style cast)}} | style="text-align:center;" | <code>(R)a</code> || {{yes}} || {{yes}} | {{cpp|1=K::operator R();}}<ref>{{cite web|url=https://en.cppreference.com/w/cpp/language/cast_operator|title=user-defined conversion|access-date=5 April 2020}}</ref> | {{n/a}} |- | {{rh}} colspan="2" | Conversion{{efn|Behaves like const_cast/static_cast/reinterpret_cast. In the last two cases, the <code>auto</code> specifier is replaced with the type of the invented variable x declared with <code>auto x(a);</code> (which is never interpreted as a function declaration) or <code>auto x{a};</code>, respectively.}}<ref>[https://en.cppreference.com/w/cpp/language/explicit_cast Explicit type conversion] in C++</ref> | style="text-align:center;" | <code>R(a)</code><br><code>R{a}</code><ref name="sinceCXX11" group="lower-alpha" /><br><code>auto(a)</code><ref name="sinceCXX23" group="lower-alpha" /><br><code>auto{a}</code><ref name="sinceCXX23" group="lower-alpha" /> || {{no}} || {{no}} | {{rh}} colspan="2" {{n/a}} |- | {{rh}} colspan="2" | static_cast conversion{{efn|For user-defined conversions, the return type implicitly and necessarily matches the operator name unless the type is inferred (e.g. {{cpp|1=operator auto()}}, {{cpp|1=operator decltype(auto)()}} etc.).}} | style="text-align:center;" | <code>'''static_cast'''<R>(a)</code> || {{yes}} || {{no}} | {{cpp|1=K::operator R();}}<br>{{cpp|1=explicit K::operator R();}}<ref name="sinceCXX11" group="lower-alpha" /> | {{n/a}} |- | {{rh}} colspan="2" | dynamic cast conversion | style="text-align:center;" | <code>'''dynamic_cast'''<R>(a)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | const_cast conversion | style="text-align:center;" | <code>'''const_cast'''<R>(a)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | reinterpret_cast conversion | style="text-align:center;" | <code>'''reinterpret_cast'''<R>(a)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Allocate memory | style="text-align:center;" | <code>'''new''' R</code><ref name="infer" group="lower-alpha"/> || {{yes}} || {{no}} | {{cpp|1=void* K::operator new(size_t x);}} | {{cpp|1=void* operator new(size_t x);}} |- | {{rh}} colspan="2" | Allocate array | style="text-align:center;" | <code>'''new''' R'''['''n''']'''</code><ref name="infer2" group="lower-alpha"/> || {{yes}} || {{no}} | {{cpp|1=void* K::operator new[](size_t a);}} | {{cpp|1=void* operator new[](size_t a);}} |- | {{rh}} colspan="2" | Deallocate memory | style="text-align:center;" | <code>'''delete''' a</code> || {{yes}} || {{no}} | {{cpp|1=void K::operator delete(void* a);}} | {{cpp|1=void operator delete(void* a);}} |- | {{rh}} colspan="2" | Deallocate array | style="text-align:center;" | <code>'''delete[]''' a</code> || {{yes}} || {{no}} | {{cpp|1=void K::operator delete[](void* a);}} | {{cpp|1=void operator delete[](void* a);}} |- | {{rh}} colspan="2" | Exception check<ref name="sinceCXX11" group="lower-alpha" /> | style="text-align:center;" | <code>'''noexcept'''(a)</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |- | {{rh}} colspan="2" | Reflection<ref name="sinceCXX26" group="lower-alpha" /> | style="text-align:center;" | <code>'''^^'''a</code> || {{no}} || {{no}} | colspan="2" {{n/a}} |}
=== Synonyms === C++ defines keywords to act as aliases for a number of operators:<ref name="Committee">{{cite book | title = ISO/IEC 14882:1998(E) Programming Language C++ | date = 1 September 1998 | publisher = open-std.org – The C++ Standards Committee | pages = 40–41}}</ref> {| class="wikitable" style="width:30%; text-align:center;" ! Keyword || Operator |- | {{code|and}} || <code>&&</code> |- | {{code|and_eq}} || <code>&=</code> |- | {{code|bitand}} || <code>&</code> |- | {{code|bitor}} || <code>|</code> |- | {{code|compl}} || <code>~</code> |- | {{code|not}} || <code>!</code> |- | {{code|not_eq}} || <code>!=</code> |- | {{code|or}} || <code>||</code> |- | {{code|or_eq}} || <code>|=</code> |- | {{code|xor}} || <code>^</code> |- | {{code|xor_eq}} || <code>^=</code> |}
Each keyword is a different way to specify an operator and as such can be used instead of the corresponding symbolic variation. For example, {{code|1=(a > 0 and not flag)}} and {{code|1=(a > 0 && !flag)}} specify the same behavior. As another example, the <code>bitand</code> keyword may be used to replace not only the ''bitwise-and'' operator but also the ''address-of'' operator, and it can be used to specify reference types (e.g., {{code|1=int bitand ref = n}}).
The ISO C specification makes allowance for these keywords as preprocessor macros in the header file {{code|iso646.h}}. For compatibility with C, C++ also provides the header {{code|iso646.h}}, the inclusion of which has no effect. Until C++20, it also provided the corresponding header {{code|ciso646}} which had no effect as well.
==Expression evaluation order== During expression evaluation, the order in which sub-expressions are evaluated is determined by precedence and associativity. An operator with higher precedence is evaluated before a operator of lower precedence and the operands of an operator are evaluated based on associativity. The following table describes the precedence and associativity of the C and C++ operators. Operators are shown in groups of equal precedence with groups ordered in descending precedence from top to bottom (lower order is higher precedence).<ref>{{cite book | title = ISO/IEC 9899:201x Programming Languages - C | date = 19 December 2011 | publisher = open-std.org – The C Standards Committee | pages = 465}}</ref><ref>{{cite tech report |title=the ISO C 1999 standard, section 6.5.6 note 71 |institution=ISO |year=1999 }}</ref><ref>{{cite web |title=C++ Built-in Operators, Precedence and Associativity |url=https://docs.microsoft.com/en-US/cpp/cpp/cpp-built-in-operators-precedence-and-associativity |website=docs.microsoft.com |access-date=11 May 2020 |language=en-us}}</ref>
Operator precedence is not affected by overloading.
{| class="wikitable" |- ! style="text-align: left" | Order ! style="text-align: left" | Operator ! style="text-align: left" | Description ! style="text-align: left" | Associativity |- ! 1 <small>highest</small> | <code>::</code> | Scope resolution (C++ only) | None |- ! rowspan=11| 2 | style="border-bottom-style: none" | <code>++</code> | style="border-bottom-style: none" | Postfix increment | style="vertical-align: top" rowspan="11" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>--</code> | style="border-bottom-style: none; border-top-style: none" | Postfix decrement |- | style="border-bottom-style: none; border-top-style: none" | <code>()</code> | style="border-bottom-style: none; border-top-style: none" | Function call |- | style="border-bottom-style: none; border-top-style: none" | <code>[]</code> | style="border-bottom-style: none; border-top-style: none" | Array subscripting |- | style="border-bottom-style: none; border-top-style: none" | <code>.</code> | style="border-bottom-style: none; border-top-style: none" | Element selection by reference |- | style="border-bottom-style: none; border-top-style: none" | <code>-></code> | style="border-bottom-style: none; border-top-style: none" | Element selection through pointer |- | style="border-bottom-style: none; border-top-style: none" | <code>typeid()</code> | style="border-bottom-style: none; border-top-style: none" | Run-time type information (C++ only) (see typeid) |- | style="border-bottom-style: none; border-top-style: none" | <code>const_cast</code> | style="border-bottom-style: none; border-top-style: none" | Type cast (C++ only) (see const_cast) |- | style="border-bottom-style: none; border-top-style: none" | <code>dynamic_cast</code> | style="border-bottom-style: none; border-top-style: none" | Type cast (C++ only) (see dynamic cast) |- | style="border-bottom-style: none; border-top-style: none" | <code>reinterpret_cast</code> | style="border-bottom-style: none; border-top-style: none" | Type cast (C++ only) (see reinterpret_cast) |- | style="border-top-style: none" | <code>static_cast</code> | style="border-top-style: none" | Type cast (C++ only) (see static_cast) |- ! rowspan="13" | 3 | style="border-bottom-style: none" | <code>++</code> | style="border-bottom-style: none" | Prefix increment | rowspan="13" style="vertical-align: top" | Right-to-left |- | style="border-bottom-style: none; border-top-style: none" | <code>--</code> | style="border-bottom-style: none; border-top-style: none" | Prefix decrement |- | style="border-bottom-style: none; border-top-style: none" | <code>+</code> | style="border-bottom-style: none; border-top-style: none" | Unary plus |- | style="border-bottom-style: none; border-top-style: none" | <code>-</code> | style="border-bottom-style: none; border-top-style: none" | Unary minus |- | style="border-bottom-style: none; border-top-style: none" | <code>!</code> | style="border-bottom-style: none; border-top-style: none" | Logical NOT |- | style="border-bottom-style: none; border-top-style: none" | <code>~</code> | style="border-bottom-style: none; border-top-style: none" | Bitwise NOT (ones' complement) |- | style="border-bottom-style: none; border-top-style: none" | <code>(''type'')</code> | style="border-bottom-style: none; border-top-style: none" | Type cast |- | style="border-bottom-style: none; border-top-style: none" | <code>*</code> | style="border-bottom-style: none; border-top-style: none" | Indirection (dereference) |- | style="border-bottom-style: none; border-top-style: none" | <code>&</code> | style="border-bottom-style: none; border-top-style: none" | Address-of |- | style="border-bottom-style: none; border-top-style: none" | <code>sizeof</code> | style="border-bottom-style: none; border-top-style: none" | Sizeof |- | style="border-bottom-style: none; border-top-style: none" | <code>_Alignof</code> | style="border-bottom-style: none; border-top-style: none" | Alignment requirement (since C11) |- | style="border-bottom-style: none; border-top-style: none" | <code>new</code>, <code>new[]</code> | style="border-bottom-style: none; border-top-style: none" | Dynamic memory allocation (C++ only) |- | style="border-top-style: none" | <code>delete</code>, <code>delete[]</code> | style="border-top-style: none" | Dynamic memory deallocation (C++ only) |- ! rowspan=2| 4 | style="border-bottom-style: none" | <code>.*</code> | style="border-bottom-style: none" | Pointer to member (C++ only) | style="vertical-align: top" rowspan="2" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>->*</code> | style="border-bottom-style: none; border-top-style: none" | Pointer to member (C++ only) |- ! rowspan=3| 5 | style="border-bottom-style: none" | <code>*</code> | style="border-bottom-style: none" | Multiplication | style="vertical-align: top" rowspan="3" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>/</code> | style="border-bottom-style: none; border-top-style: none" | Division |- | style="border-bottom-style: none; border-top-style: none" | <code>%</code> | style="border-bottom-style: none; border-top-style: none" | Modulo (remainder) |- ! rowspan=2| 6 | style="border-bottom-style: none" | <code>+</code> | style="border-bottom-style: none" | Addition | style="vertical-align: top" rowspan="2" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>-</code> | style="border-bottom-style: none; border-top-style: none" | Subtraction |- ! rowspan=2| 7 | style="border-bottom-style: none" | <code><<</code> | style="border-bottom-style: none" | Bitwise left shift | style="vertical-align: top" rowspan="2" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>>></code> | style="border-bottom-style: none; border-top-style: none" | Bitwise right shift |- ! rowspan=1| 8 | style="border-bottom-style:none;" | <code><=></code> | style="border-bottom-style:none;" | Three-way comparison (Introduced in C++20 - C++ only) | style="vertical-align: top" rowspan="1" | Left-to-right |- ! rowspan=4| 9 | style="border-bottom-style: none" | <code><</code> | style="border-bottom-style: none" | Less than | style="vertical-align: top" rowspan="4" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code><=</code> | style="border-bottom-style: none; border-top-style: none" | Less than or equal to |- | style="border-bottom-style: none; border-top-style: none" | <code>></code> | style="border-bottom-style: none; border-top-style: none" | Greater than |- | style="border-bottom-style: none; border-top-style: none" | <code>>=</code> | style="border-bottom-style: none; border-top-style: none" | Greater than or equal to |- ! rowspan=2| 10 | style="border-bottom-style: none" | <code>==</code> | style="border-bottom-style: none" | Equal to | style="vertical-align: top" rowspan="2" | Left-to-right |- | style="border-bottom-style: none; border-top-style: none" | <code>!=</code> | style="border-bottom-style: none; border-top-style: none" | Not equal to |- ! 11 | <code>&</code> | Bitwise AND | Left-to-right |- ! 12 | <code>^</code> | Bitwise XOR (exclusive or) | Left-to-right |- ! 13 | <code><nowiki>|</nowiki></code> | Bitwise OR (inclusive or) | Left-to-right |- ! 14 | <code>&&</code> | Logical AND | Left-to-right |- ! 15 | <code><nowiki>||</nowiki></code> | Logical OR | Left-to-right |- ! rowspan="2" | 16 | style="border-bottom-style: none" | <code>co_await</code> | rowspan="2" | Coroutine processing (C++ only) | rowspan="2" | Right-to-left |- | style="border-top-style: none" | <code>co_yield</code> |- ! rowspan="13" | 17 | style="border-bottom-style: none" | <code>?:</code> | style="border-bottom-style: none" | Ternary conditional operator | rowspan="13" | Right-to-left |- | style="border-bottom-style: none; border-top-style: none" | <code>=</code> | style="border-bottom-style: none; border-top-style: none" | Direct assignment |- | style="border-bottom-style: none; border-top-style: none" | <code>+=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by sum |- | style="border-bottom-style: none; border-top-style: none" | <code>-=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by difference |- | style="border-bottom-style: none; border-top-style: none" | <code>*=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by product |- | style="border-bottom-style: none; border-top-style: none" | <code>/=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by quotient |- | style="border-bottom-style: none; border-top-style: none" | <code>%=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by remainder |- | style="border-bottom-style: none; border-top-style: none" | <code><<=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by bitwise left shift |- | style="border-bottom-style: none; border-top-style: none" | <code>>>=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by bitwise right shift |- | style="border-bottom-style: none; border-top-style: none" | <code>&=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by bitwise AND |- | style="border-bottom-style: none; border-top-style: none" | <code>^=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by bitwise XOR |- | style="border-bottom-style: none; border-top-style: none" | <code><nowiki>|</nowiki>=</code> | style="border-bottom-style: none; border-top-style: none" | Assignment by bitwise OR |- | style="border-top-style: none" | <code>throw</code> | style="border-top-style: none" | Throw operator (exceptions throwing, C++ only) |- ! 18 <small>lowest</small> | <code>,</code> | Comma | Left-to-right |}
===Details=== Although this table is adequate for describing most evaluation order, it does not describe a few details. The ternary operator allows any arbitrary expression as its middle operand, despite being listed as having higher precedence than the assignment and comma operators. Thus <code>a ? b, c : d</code> is interpreted as <code>a ? (b, c) : d</code>, and not as the meaningless <code>(a ? b), (c : d)</code>. So, the expression in the middle of the conditional operator (between <code>'''?'''</code> and <code>''':'''</code>) is parsed as if parenthesized. Also, the immediate, un-parenthesized result of a C cast expression cannot be the operand of <code>sizeof</code>. Therefore, <code>sizeof (int) * x</code> is interpreted as <code>(sizeof(int)) * x</code> and not <code>sizeof ((int) * x)</code>.
===Chained expressions=== The precedence table determines the order of binding in chained expressions, when it is not expressly specified by parentheses. * For example, <code>++x*3</code> is ambiguous without some precedence rule(s). The precedence table tells us that: {{mono|x}} is 'bound' more tightly to {{mono|++}} than to {{mono|*}}, so that whatever {{mono|++}} does (now or later—see below), it does it ONLY to {{mono|x}} (and not to <code>x*3</code>); it is equivalent to (<code>++x</code>, <code>x*3</code>). * Similarly, with <code>3*x++</code>, where though the post-fix {{mono|++}} is designed to act AFTER the entire expression is evaluated, the precedence table makes it clear that ONLY {{mono|x}} gets incremented (and NOT <code>3*x</code>). In fact, the expression (<code>tmp=x++</code>, <code>3*tmp</code>) is evaluated with {{mono|tmp}} being a temporary value. It is functionally equivalent to something like (<code>tmp=3*x</code>, <code>++x</code>, <code>tmp</code>). center|thumb|Precedence and bindings * Abstracting the issue of precedence or binding, consider the diagram above for the expression 3+2*y[i]++. The compiler's job is to resolve the diagram into an expression, one in which several unary operators (call them 3+( . ), 2*( . ), ( . )++ and ( . )[ i ]) are competing to bind to y. The order of precedence table resolves the final sub-expression they each act upon: ( . )[ i ] acts only on y, ( . )++ acts only on y[i], 2*( . ) acts only on y[i]++ and 3+( . ) acts 'only' on 2*((y[i])++). WHAT sub-expression gets acted on by each operator is clear from the precedence table but WHEN each operator acts is not resolved by the precedence table; in this example, the ( . )++ operator acts only on y[i] by the precedence rules but binding levels alone do not indicate the timing of the postfix ++ (the ( . )++ operator acts only after y[i] is evaluated in the expression).
===Binding=== The binding of operators in C and C++ is specified by a factored language grammar, rather than a precedence table. This creates some subtle conflicts. For example, in C, the syntax for a conditional expression is: <syntaxhighlight lang="c">logical-OR-expression ? expression : conditional-expression</syntaxhighlight> while in C++ it is: <syntaxhighlight lang="cpp">logical-OR-expression ? expression : assignment-expression</syntaxhighlight> Hence, the expression: <syntaxhighlight lang="text">e = a < d ? a++ : a = d</syntaxhighlight> is parsed differently in the two languages. In C, this expression is a syntax error, because the syntax for an assignment expression in C is: <syntaxhighlight lang="c">unary-expression '=' assignment-expression</syntaxhighlight> In C++, it is parsed as: <syntaxhighlight lang="cpp">e = (a < d ? a++ : (a = d))</syntaxhighlight> which is a valid expression.<ref>{{cite web |title=C Operator Precedence - cppreference.com |url=https://en.cppreference.com/w/c/language/operator_precedence |website=en.cppreference.com |access-date=10 April 2020}}</ref><ref>{{Cite web|url=https://stackoverflow.com/questions/13515434/does-the-c-c-ternary-operator-actually-have-the-same-precedence-as-assignment/13515505|title=Does the C/C++ ternary operator actually have the same precedence as assignment operators?|website=Stack Overflow|access-date=2019-09-22}}</ref>
To use the comma operator in a function call argument expression, variable assignment, or a comma-separated list, use of parentheses is required.<ref>{{cite web |title=Other operators - cppreference.com |url=https://en.cppreference.com/w/c/language/operator_other |website=en.cppreference.com |access-date=10 April 2020}}</ref><ref>{{cite web |title=c++ - How does the Comma Operator work |url=https://stackoverflow.com/questions/54142/how-does-the-comma-operator-work/ |website=Stack Overflow |access-date=1 April 2020}}</ref> For example,
<syntaxhighlight lang="cpp"> int a = 1, b = 2, weirdVariable = (++a, b), d = 4; </syntaxhighlight>
===Criticism of bitwise and equality operators precedence=== The precedence of the bitwise logical operators has been criticized.<ref name="Bell">{{Citation | url = https://www.bell-labs.com/usr/dmr/www/chist.html | title = C history § Neonatal C| publisher = Bell labs}}.</ref> Conceptually, & and | are arithmetic operators like * and +.
The expression {{cpp|1=a & b == 7}} is syntactically parsed as {{cpp|1=a & (b == 7)}} whereas the expression {{cpp |1=a + b == 7}} is parsed as {{cpp|1=(a + b) == 7}}. This requires parentheses to be used more often than they otherwise would.
Historically, there was no syntactic distinction between the bitwise and logical operators. In BCPL, B and early C, the operators {{cpp|&& {{!!}}}} didn't exist. Instead {{cpp|& {{!}}}} had different meaning depending on whether they are used in a 'truth-value context' (i.e. when a Boolean value was expected, for example in {{cpp|1= if (a==b & c) {...} }} it behaved as a logical operator, but in {{cpp|1= c = a & b}} it behaved as a bitwise one). It was retained so as to keep backward compatibility with existing installations.<ref>{{cite web|url=https://www.perlmonks.org/?node_id=1159769|title=Re^10: next unless condition|website=www.perlmonks.org|access-date=23 March 2018}}</ref>
Moreover, in C++ (and later versions of C) equality operations, with the exception of the three-way comparison operator, yield bool type values which are conceptually a single bit (1 or 0) and as such do not properly belong in "bitwise" operations.
==Notes== {{reflist |group="lower-alpha"|refs= <ref name="sinceCXX11" group="lower-alpha">since C++11</ref> <ref name="sinceCXX23" group="lower-alpha">since C++23</ref> <ref name="sinceCXX26" group="lower-alpha">since C++26</ref> <ref name="typeof" group="lower-alpha">since C23; not in standard C++</ref> <ref name="modulo" group="lower-alpha">The modulus operator only supports integer operands; for floating point, a function such as {{code|fmod|cpp}} can be used.</ref> <ref name="bitshift" group="lower-alpha">In the context of iostreams in C++, writers often will refer to {{cpp|<<}} and {{cpp|>>}} as the "put-to" or "stream insertion" and "get-from" or "stream extraction" operators, respectively.</ref> <ref name="addressof2" group="lower-alpha">The actual address of an object with an overloaded <code>operator &</code> can be obtained with [https://en.cppreference.com/w/cpp/memory/addressof <code>std::addressof</code>]</ref> <ref name="arrowptr" group="lower-alpha">The return type of {{cpp|operator->()}} must be a type for which the {{cpp |->}} operation can be applied, such as a pointer type. If {{cpp|x}} is of type {{cpp |C}} where {{cpp |C}} overloads {{cpp|operator->()}}, {{cpp|x->y}} gets expanded to {{cpp|x.operator->()->y}}.</ref> <ref name="arrowstar" group= "lower-alpha">{{Citation | publisher = Aristeia | url = http://aristeia.com/Papers/DDJ_Oct_1999.pdf | title = Implementing operator->* for Smart Pointers | first = Scott | last = Meyers | journal = Dr. Dobb's Journal |date=Oct 1999}}.</ref> <ref name="scopal" group="lower-alpha">Although a <code>::</code> punctuator exists in C as of C23, it is not used as a scope resolution operator.</ref> <ref name="ud-literal" group="lower-alpha">About [http://en.cppreference.com/w/cpp/language/user_literal C++11 User-defined literals]</ref> <ref name="sizeof" group="lower-alpha">The parentheses are not necessary when taking the size of a value, only when taking the size of a type. However, they are usually used regardless.{{Citation needed|date=July 2024}}</ref> <ref name="alignof" group = "lower-alpha">C++ defines <code>alignof</code> operator, whereas C defines <code>_Alignof</code> (C23 defines both). Both operators have the same semantics.</ref> <ref name="threewaycomparison" group="lower-alpha">About [https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison C++20 three-way comparison]</ref>
<ref name="infer" group="lower-alpha">The type name can also be inferred (e.g <code>new auto</code>) if an initializer is provided.</ref> <ref name="infer2" group="lower-alpha">The array size can also be inferred if an initializer is provided.</ref> }}
==See also== * {{Annotated link|Bitwise operations in C}} * {{Annotated link|Bit manipulation}} * {{Annotated link|Logical operator}} * {{Annotated link|Boolean algebra (logic)}} * {{Annotated link|Table of logic symbols}}
== References == {{Reflist|30em}}
==External links== * {{Citation | url = https://en.cppreference.com/w/cpp/language/expressions#Operators | contribution = Operators | title = C++ reference | type = wiki}}. *[https://en.cppreference.com/w/c/language/operator_precedence C Operator Precedence] * {{Citation | url = https://docs.microsoft.com/en-US/cpp/cpp/postfix-increment-and-decrement-operators-increment-and-decrement | title = Postfix Increment and Decrement Operators: ++ and -- | date = 17 August 2021 | type = Developer network | publisher = Microsoft}}.
{{CProLang}} {{C++ programming language}}
{{DEFAULTSORT:Operators in C And C}} Category:C (programming language) Category:C++ Category:Articles with example C++ code Category:Operators (programming) Category:Comparison of individual programming languages