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 |
|
|
|
|
|
|
|
Special operators | ||||||
|
- operator precedence defines the order in which operators are bound to their arguments
- alternative representations are alternative spellings for some operators
- operator overloading makes it possible to specify the behavior of the operators with user-defined classes.
Conversions
- standard conversions implicit conversions from one type to another
-
const_cast
conversion -
static_cast
conversion -
dynamic_cast
conversion -
reinterpret_cast
conversion - explicit cast conversion using C-style cast notation and functional notation
- user-defined conversion makes it possible to specify conversion from user-defined classes
Memory allocation
- new expression allocates memory dynamically
- delete expression deallocates memory dynamically
Other
- constant expressions can be evaluated at compile time and used in compile-time context (template arguments, array sizes, etc)
-
sizeof
-
alignof
-
typeid
- throw-expression
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:
-
this
- Literals (e.g.
2
or"Hello, world"
) - Id-expressions, including
- suitably declared unqualified identifiers (e.g.
n
orcout
), and - suitably declared qualified identifiers (e.g.
std::string::npos
)
- suitably declared unqualified identifiers (e.g.
(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.
- integer literals are decimal, octal, hexadecimal or binary numbers of integer type.
- character literals are individual characters of type
-
char
orwchar_t
|
(since C++11) |
|
(since C++20) |
- floating-point literals are values of type
float
,double
, orlong double
- string literals are sequences of characters of type
-
const char[]
orconst wchar_t[]
|
(since C++11) |
|
(since C++20) |
- boolean literals are values of type
bool
, that istrue
andfalse
|
(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 |
(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 |
(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