cpp / latest / language / expressions.html /

Expressions

An expression is a sequence of operators and their operands, that specifies a computation.

Expression evaluation may produce a result (e.g., evaluation of 2 + 2 produces the result 4) and may generate side-effects (e.g. evaluation of std::printf("%d",4) prints the character '4' on the standard output).

Each C++ expression is characterized by two independent properties: A type and a value category.

General

  • value categories (lvalue, rvalue, glvalue, prvalue, xvalue (since C++11)) classify expressions by their values
  • order of evaluation of arguments and subexpressions specify the order in which intermediate results are obtained

Operators

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 >>= b.

++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 >> b.

!a a && b a || b.

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

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

a(...) a, b a ? b : c.

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 creates objects with dynamic storage duration
delete destructs objects previously created by the new expression and releases obtained memory area
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).

Conversions

Memory allocation

Other

Primary expressions

The operands of any operator may be other expressions or primary expressions (e.g. in 1 + 2 * 3, the operands of operator+ are the subexpression 2 * 3 and the primary expression 1).

Primary expressions are any of the following:

(since C++11)
(since C++17)
(since C++20)

Any expression in parentheses is also classified as a primary expression: this guarantees that the parentheses have higher precedence than any operator. Parentheses preserve value, type, and value category.

Literals

Literals are the tokens of a C++ program that represent constant values embedded in the source code.

  • char16_t or char32_t
(since C++11)
  • char8_t
(since C++20)
  • const char16_t[] or const char32_t[]
(since C++11)
  • const char8_t[]
(since C++20)
(since C++11)

Unevaluated expressions

The operands of the operators typeid, sizeof, noexcept, and decltype (since C++11) are expressions that are not evaluated (unless they are polymorphic glvalues and are the operands of typeid), since these operators only query the compile-time properties of their operands. Thus, std::size_t n = sizeof(std::cout << 42); does not perform console output.

The unevaluated operands are considered to be full expressions even though they are syntactically operands in a larger expression (for example, this means that sizeof(T()) requires an accessible T::~T).

(since C++14)

The requires-expressions are also unevaluated expressions.

(since C++20)

Discarded-value expressions

A discarded-value expression is an expression that is used for its side-effects only. The value calculated from such expression is discarded. Such expressions include the full expression of any expression statement, the left-hand operand of the built-in comma operator, or the operand of a cast-expression that casts to the type void.

Array-to-pointer and function-to-pointer conversions are never applied to the value calculated by a discarded-value expression. The lvalue-to-rvalue conversion is applied if and only if the expression is a volatile-qualified glvalue and has one of the following forms (built-in meaning required, possibly parenthesized):

  • id-expression,
  • array subscript expression,
  • class member access expression,
  • indirection,
  • pointer-to-member operation,
  • conditional expression where both the second and the third operands are one of these expressions,
  • comma expression where the right operand is one of these expressions.

In addition, if the lvalue is of volatile-qualified class type, a volatile copy constructor is required to initialize the resulting rvalue temporary.

If the expression is a non-void prvalue (after any lvalue-to-rvalue conversion that might have taken place), temporary materialization occurs.

Compilers may issue warnings when an expression other than cast to void discards a value declared [[nodiscard]].

(since C++17)

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 1054 C++98 assigning a value to a volatile variable might
result in an unnecessary read due to the lvalue-to-
rvalue conversion applied to the assignment result
introduce discarded-value expressions
and exclude this case from the list
of cases that require the conversion
CWG 1383 C++98 the list of expressions where lvalue-to-rvalue
conversion is applied for discarded-value
expressions also covered overloaded operators
only cover operators
with built-in meaning

See also

C documentation for Expressions

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/expressions