Quire
Redirected from Function call operator

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 &&, ||, and , (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, += and -= are often called "plus equal(s)" and "minus equal(s)", instead of the more verbose "assignment by addition" and "assignment by subtraction".

Operators#edit

In the following tables, lower case letters such as a and b represent literal values, object/variable names, or l-values, as appropriate. R, S and T stand for a data type, and K for a class or enumeration type. Some operators have alternative spellings using digraphs and trigraphs or operator synonyms.

Arithmetic#edit

C and C++ have the same arithmetic operators and all can be overloaded in C++.

OperationSyntaxC++ prototype
in class Koutside class
Additiona + bR K::operator +(S b);R operator +(K a, S b);
Subtractiona - bR K::operator -(S b);R operator -(K a, S b);
Unary plus; integer promotion+aR K::operator +();R operator +(K a);
Unary minus; additive inverse-aR K::operator -();R operator -(K a);
Multiplicationa * bR K::operator *(S b);R operator *(K a, S b);
Divisiona / bR K::operator /(S b);R operator /(K a, S b);
Modulo[1]a % bR K::operator %(S b);R operator %(K a, S b);
Prefix increment++aR& K::operator ++();R& operator ++(K& a);
Postfix incrementa++R K::operator ++(int);[2]R operator ++(K& a, int);[2]
Prefix decrement--aR& K::operator --();R& operator --(K& a);
Postfix decrementa--R K::operator --(int);[2]R operator --(K& a, int);[2]

Relational#edit

All relational (comparison) operators can be overloaded in C++. Since C++20, the inequality operator is automatically generated if operator== is defined and all four relational operators are automatically generated if operator<=> is defined.[3]

OperationSyntaxIn CC++ prototype
in class Koutside class
Equal toa == bYesbool K::operator ==(S const& b) const;bool operator ==(K const& a, S const& b);
Not equal toa != bYesbool K::operator !=(S const& b) const;bool operator !=(K const& a, S const& b);
Greater thana > bYesbool K::operator >(S const& b) const;bool operator >(K const& a, S const& b);
Less thana < bYesbool K::operator <(S const& b) const;bool operator <(K const& a, S const& b);
Greater than or equal toa >= bYesbool K::operator >=(S const& b) const;bool operator >=(K const& a, S const& b);
Less than or equal toa <= bYesbool K::operator <=(S const& b) const;bool operator <=(K const& a, S const& b);
Three-way comparison[4][5]a <=> bNoauto K::operator <=>(const S &b);auto operator <=>(const K &a, const S &b);

Logical#edit

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.[6]

OperationSyntaxC++ prototype
in class Koutside class
NOT!abool K::operator !();bool operator !(K a);
ANDa && bbool K::operator &&(S b);bool operator &&(K a, S b);
ORa || bbool K::operator ||(S b);bool operator ||(K a, S b);

Bitwise#edit

C and C++ have the same bitwise operators and all can be overloaded in C++.

OperationSyntaxC++ prototype
in class Koutside class
NOT~aR K::operator ~();R operator ~(K a);
ANDa & bR K::operator &(S b);R operator &(K a, S b);
ORa | bR K::operator |(S b);R operator |(K a, S b);
XORa ^ bR K::operator ^(S b);R operator ^(K a, S b);
Shift left[7]a << bR K::operator <<(S b);R operator <<(K a, S b);
Shift right[7][8]a >> bR K::operator >>(S b);R operator >>(K a, S b);

Assignment#edit

C and C++ have the same assignment operators and all can be overloaded in C++.

For the combination operators, a ⊚= b (where ⊚ represents an operation) is equivalent to a = a ⊚ b, except that a is evaluated only once.

OperationSyntaxC++ prototype
in class Koutside class
Assignmenta = bR& K::operator =(S b);—N/a
Addition combinationa += bR& K::operator +=(S b);R& operator +=(K& a, S b);
Subtraction combinationa -= bR& K::operator -=(S b);R& operator -=(K& a, S b);
Multiplication combinationa *= bR& K::operator *=(S b);R& operator *=(K& a, S b);
Division combinationa /= bR& K::operator /=(S b);R& operator /=(K& a, S b);
Modulo combinationa %= bR& K::operator %=(S b);R& operator %=(K& a, S b);
Bitwise AND combinationa &= bR& K::operator &=(S b);R& operator &=(K& a, S b);
Bitwise OR combinationa |= bR& K::operator |=(S b);R& operator |=(K& a, S b);
Bitwise XOR combinationa ^= bR& K::operator ^=(S b);R& operator ^=(K& a, S b);
Bitwise left shift combinationa <<= bR& K::operator <<=(S b);R& operator <<=(K& a, S b);
Bitwise right shift combination[9]a >>= bR& K::operator >>=(S b);R& operator >>=(K& a, S b);

Member and pointer#edit

OperationSyntaxCan overloadIn CC++ prototype
in class Koutside class
Subscripta[b]
a<:b:>[10]
YesYesR& K::operator [](S b);
R& K::operator [](S b, ...);[11]
—N/a
Indirection
(object pointed to by a)
*aYesYesR& K::operator *();R& operator *(K a);
Address-of
(address of a)
&aYes[12]YesR* K::operator &();R* operator &(K a);
Structure dereference
(member b of object pointed to by a)
a->bYesYesR* K::operator ->();[13]—N/a
Structure reference
(member b of object a)
a.bNoYes—N/a
Member selected by pointer-to-member b of object pointed to by a[14]a->*bYesNoR& K::operator ->*(S b);R& operator ->*(K a, S b);
Member of object a selected by pointer-to-member ba.*bNoNo—N/a

Other#edit

OperationSyntaxCan overloadIn CC++ prototype
in class Koutside class
Function calla(a1, a2)YesYesR K::operator ()(S a, T b, ...);—N/a
Commaa, bYesYesR K::operator ,(S b);R operator ,(K a, S b);
Ternary conditionala ? b : cNoYes—N/a
Scope resolutiona::b[15]NoNo—N/a
User-defined literals[16][17]"a"_bYesNo—N/aR operator "" _b(T a)
Sizeofsizeof a[18]
sizeof (R)
NoYes—N/a
Size of parameter pack[17]sizeof...(Args)NoNo—N/a
Alignof[17]alignof(R)
or _Alignof(R)[19]
NoYes—N/a
Typeof[20]typeof(a)
typeof(R)
typeof_unqual(a)
typeof_unqual(R)
—N/aYes—N/a
Decltype[17]decltype(a)
decltype(R)
NoNo—N/a
Type identificationtypeid(a)
typeid(R)
NoNo—N/a
Conversion
(C-style cast)
(R)aYesYesK::operator R();[21]—N/a
Conversion[22][23]R(a)
R{a}[17]
auto(a)[11]
auto{a}[11]
NoNo—N/a
static_cast conversion[24]static_cast<R>(a)YesNoK::operator R();
explicit K::operator R();[17]
—N/a
dynamic cast conversiondynamic_cast<R>(a)NoNo—N/a
const_cast conversionconst_cast<R>(a)NoNo—N/a
reinterpret_cast conversionreinterpret_cast<R>(a)NoNo—N/a
Allocate memorynew R[25]YesNovoid* K::operator new(size_t x);void* operator new(size_t x);
Allocate arraynew R[n][26]YesNovoid* K::operator new[](size_t a);void* operator new[](size_t a);
Deallocate memorydelete aYesNovoid K::operator delete(void* a);void operator delete(void* a);
Deallocate arraydelete[] aYesNovoid K::operator delete[](void* a);void operator delete[](void* a);
noexcept clause[17]noexcept(a)NoNo—N/a
requires clause[17]requires (a)NoNo—N/a
Reflection[27]^^aNoNo—N/a

Synonyms#edit

C++ defines keywords to act as aliases for a number of operators:[28]

KeywordOperator
and&&
and_eq&=
bitand&
bitor|
compl~
not!
not_eq!=
or||
or_eq|=
xor^
xor_eq^=

Each keyword is a different way to specify an operator and as such can be used instead of the corresponding symbolic variation. For example, a > 0 and not flag and a > 0 && !flag specify the same behavior. As another example, the bitand 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., int bitand ref = n;).

The ISO C specification makes allowance for these keywords as preprocessor macros in the header file <iso646.h>. For compatibility with C, C++ also provides the header <iso646.h>, the inclusion of which has no effect. Until C++20, it also provided the corresponding header <ciso646> which had no effect as well.

Expression evaluation order#edit

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).[29][30][31]

Operator precedence is not affected by overloading.

OrderOperatorDescriptionAssociativity
1
highest
::Scope resolution (C++ only)None
2++Postfix incrementLeft-to-right
--Postfix decrement
()Function call
[]Array subscripting
.Element selection by reference
->Element selection through pointer
typeid()Run-time type information (C++ only) (see typeid)
const_castType cast (C++ only) (see const_cast)
dynamic_castType cast (C++ only) (see dynamic cast)
reinterpret_castType cast (C++ only) (see reinterpret_cast)
static_castType cast (C++ only) (see static_cast)
3++Prefix incrementRight-to-left
--Prefix decrement
+Unary plus
-Unary minus
!Logical NOT
~Bitwise NOT (ones' complement)
(type)Type cast
*Indirection (dereference)
&Address-of
sizeofSizeof
alignofAlignment requirement (since C11)
new, new[]Dynamic memory allocation (C++ only)
delete, delete[]Dynamic memory deallocation (C++ only)
4.*Pointer to member (C++ only)Left-to-right
->*Pointer to member (C++ only)
5*MultiplicationLeft-to-right
/Division
%Modulo (remainder)
6+AdditionLeft-to-right
-Subtraction
7<<Bitwise left shiftLeft-to-right
>>Bitwise right shift
8<=>Three-way comparison (Introduced in C++20 - C++ only)Left-to-right
9<Less thanLeft-to-right
<=Less than or equal to
>Greater than
>=Greater than or equal to
10==Equal toLeft-to-right
!=Not equal to
11&Bitwise ANDLeft-to-right
12^Bitwise XOR (exclusive or)Left-to-right
13|Bitwise OR (inclusive or)Left-to-right
14&&Logical ANDLeft-to-right
15||Logical ORLeft-to-right
16co_awaitCoroutine processing (C++ only)Right-to-left
co_yield
17?:Ternary conditional operatorRight-to-left
=Direct assignment
+=Assignment by sum
-=Assignment by difference
*=Assignment by product
/=Assignment by quotient
%=Assignment by remainder
<<=Assignment by bitwise left shift
>>=Assignment by bitwise right shift
&=Assignment by bitwise AND
^=Assignment by bitwise XOR
|=Assignment by bitwise OR
throwThrow operator (exceptions throwing, C++ only)
18
lowest
,CommaLeft-to-right

Details#edit

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 a ? b, c : d is interpreted as a ? (b, c) : d, and not as the meaningless (a ? b), (c : d). So, the expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized. Also, the immediate, un-parenthesized result of a C cast expression cannot be the operand of sizeof. Therefore, sizeof(int) * x is interpreted as (sizeof(int)) * x and not sizeof((int) * x).

Chained expressions#edit

The precedence table determines the order of binding in chained expressions, when it is not expressly specified by parentheses.

  • For example, ++x*3 is ambiguous without some precedence rule(s). The precedence table tells us that: x is 'bound' more tightly to ++ than to *, so that whatever ++ does (now or later—see below), it does it ONLY to x (and not to x*3); it is equivalent to (++x, x*3).
  • Similarly, with 3*x++, where though the post-fix ++ is designed to act AFTER the entire expression is evaluated, the precedence table makes it clear that ONLY x gets incremented (and NOT 3*x). In fact, the expression (tmp=x++, 3*tmp) is evaluated with tmp being a temporary value. It is functionally equivalent to something like (tmp=3*x, ++x, tmp).
Precedence and bindings
Precedence and bindings Image: source and license
  • 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#edit

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:

logical-OR-expression ? expression : conditional-expression

while in C++ it is:

logical-OR-expression ? expression : assignment-expression

Hence, the expression:

e = a < d ? a++ : a = d

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:

unary-expression '=' assignment-expression

In C++, it is parsed as:

e = (a < d ? a++ : (a = d))

which is a valid expression.[32][33]

To use the comma operator in a function call argument expression, variable assignment, or a comma-separated list, use of parentheses is required.[34][35] For example,

int a = 1, b = 2, weirdVariable = (++a, b), d = 4;

Criticism of bitwise and equality operators precedence#edit

The precedence of the bitwise logical operators has been criticized.[36] Conceptually, & and | are arithmetic operators like * and +.

The expression a & b == 7 is syntactically parsed as a & (b == 7) whereas the expression a + b == 7 is parsed as (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 && || didn't exist. Instead & | 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 if (a == b & c) { /* ... */ } it behaved as a logical operator, but in c = a & b it behaved as a bitwise one). It was retained so as to keep backward compatibility with existing installations.[37]

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#edit

  1. ^ The modulus operator only supports integer operands; for floating point, a function such as fmod can be used.
  2. ^ a b c d The int is a dummy parameter to differentiate between prefix and postfix.
  3. ^ "Operator overloading§Comparison operators". cppreference.com.
  4. ^ About C++20 three-way comparison
  5. ^ Possible return types: std::weak_ordering, std::strong_ordering and std::partial_ordering to which they all are convertible to.
  6. ^ "Standard C++".
  7. ^ a b In the context of iostreams in C++, writers often will refer to << and >> as the "put-to" or "stream insertion" and "get-from" or "stream extraction" operators, respectively.
  8. ^ According to the C99 standard, the right shift of a negative number is implementation defined. Most implementations, e.g., the GCC, name="Integers-8">"Integers implementation", GCC 4.3.3, GNU.> use an arithmetic shift (i.e., sign extension), but a logical shift is possible.
  9. ^ According to the C99 standard, the right shift of a negative number is implementation defined. Most implementations, e.g., the GCC, name="Integers-8"/> use an arithmetic shift (i.e., sign extension), but a logical shift is possible.
  10. ^ "ISO/IEC 9899:1999 specification, TC3" (PDF). p. 64, § 6.4.6 Ponctuators para. 3.
  11. ^ a b c since C++23
  12. ^ The actual address of an object with an overloaded operator & can be obtained with std::addressof
  13. ^ The return type of operator->() must be a type for which the -> operation can be applied, such as a pointer type. If x is of type C where C overloads operator->(), x->y gets expanded to x.operator->()->y.
  14. ^ Meyers, Scott (October 1999), "Implementing operator->* for Smart Pointers" (PDF), Dr. Dobb's Journal, Aristeia.
  15. ^ Although a :: punctuator exists in C as of C23, it is not used as a scope resolution operator.
  16. ^ About C++11 User-defined literals
  17. ^ a b c d e f g h since C++11
  18. ^ 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]
  19. ^ C++ defines alignof operator, whereas C defines _Alignof (C23 defines both). Both operators have the same semantics.
  20. ^ since C23; not in standard C++
  21. ^ "user-defined conversion". Retrieved 5 April 2020.
  22. ^ Behaves like const_cast/static_cast/reinterpret_cast. In the last two cases, the auto specifier is replaced with the type of the invented variable x declared with auto x(a); (which is never interpreted as a function declaration) or auto x{a};, respectively.
  23. ^ Explicit type conversion in C++
  24. ^ For user-defined conversions, the return type implicitly and necessarily matches the operator name unless the type is inferred (e.g. operator auto(), operator decltype(auto)() etc.).
  25. ^ The type name can also be inferred (e.g new auto) if an initializer is provided.
  26. ^ The array size can also be inferred if an initializer is provided.
  27. ^ since C++26
  28. ^ ISO/IEC 14882:1998(E) Programming Language C++. open-std.org – The C++ Standards Committee. 1 September 1998. pp. 40–41.
  29. ^ ISO/IEC 9899:201x Programming Languages - C. open-std.org – The C Standards Committee. 19 December 2011. p. 465.
  30. ^ the ISO C 1999 standard, section 6.5.6 note 71 (Technical report). ISO. 1999.
  31. ^ "C++ Built-in Operators, Precedence and Associativity". docs.microsoft.com. Retrieved 11 May 2020.
  32. ^ "C Operator Precedence - cppreference.com". en.cppreference.com. Retrieved 10 April 2020.
  33. ^ "Does the C/C++ ternary operator actually have the same precedence as assignment operators?". Stack Overflow. Retrieved 22 September 2019.
  34. ^ "Other operators - cppreference.com". en.cppreference.com. Retrieved 10 April 2020.
  35. ^ "c++ - How does the Comma Operator work". Stack Overflow. Retrieved 1 April 2020.
  36. ^ C history § Neonatal C, Bell labs.
  37. ^ "Re^10: next unless condition". www.perlmonks.org. Retrieved 23 March 2018.

See also#edit

This article is mirrored from “Operators in C and C++” on English Wikipedia, revision 1369610893, written by Wikipedia's contributors and licensed CC BY-SA 4.0. Editing it here creates a Quire copy with its own history.

Synced with Wikipedia revision 1369610893 · just now