499 lines
24 KiB
Markdown
499 lines
24 KiB
Markdown
[expr.prop]
|
||
|
||
# 7 Expressions [[expr]](./#expr)
|
||
|
||
## 7.2 Properties of expressions [expr.prop]
|
||
|
||
### [7.2.1](#basic.lval) Value category [[basic.lval]](basic.lval)
|
||
|
||
[1](#basic.lval-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L140)
|
||
|
||
Expressions are categorized according to the taxonomy in Figure [2](#fig:basic.lval)[.](#basic.lval-1.sentence-1)
|
||
|
||

|
||
Figure [2](#fig:basic.lval) — Expression category taxonomy [[fig:basic.lval]](./fig:basic.lval)
|
||
|
||
- [(1.1)](#basic.lval-1.1)
|
||
|
||
A [*glvalue*](#def:glvalue "7.2.1 Value category [basic.lval]") is an expression whose evaluation determines the identity of an object, function, or non-static data member[.](#basic.lval-1.1.sentence-1)
|
||
|
||
- [(1.2)](#basic.lval-1.2)
|
||
|
||
A [*prvalue*](#def:prvalue "7.2.1 Value category [basic.lval]") is an expression whose evaluation initializes an object
|
||
or computes the value of an operand of an operator,
|
||
as specified by the context in which it appears,
|
||
or an expression that has type cv void[.](#basic.lval-1.2.sentence-1)
|
||
|
||
- [(1.3)](#basic.lval-1.3)
|
||
|
||
An [*xvalue*](#def:xvalue "7.2.1 Value category [basic.lval]") is a glvalue that denotes an object whose resources can be reused (usually because it is near the end of its lifetime)[.](#basic.lval-1.3.sentence-1)
|
||
|
||
- [(1.4)](#basic.lval-1.4)
|
||
|
||
An [*lvalue*](#def:lvalue "7.2.1 Value category [basic.lval]") is a glvalue that is not an xvalue[.](#basic.lval-1.4.sentence-1)
|
||
|
||
- [(1.5)](#basic.lval-1.5)
|
||
|
||
An [*rvalue*](#def:rvalue "7.2.1 Value category [basic.lval]") is a prvalue or an xvalue[.](#basic.lval-1.5.sentence-1)
|
||
|
||
[2](#basic.lval-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L160)
|
||
|
||
Every expression belongs to exactly one of the fundamental categories in this
|
||
taxonomy: lvalue, xvalue, or prvalue[.](#basic.lval-2.sentence-1)
|
||
|
||
This property of an expression is called
|
||
its [*value category*](#def:value_category "7.2.1 Value category [basic.lval]")[.](#basic.lval-2.sentence-2)
|
||
|
||
[*Note [1](#basic.lval-note-1)*:
|
||
|
||
The discussion of each built-in operator in[[expr.compound]](expr.compound "7.6 Compound expressions") indicates the category of the value it yields and the value categories
|
||
of the operands it expects[.](#basic.lval-2.sentence-3)
|
||
|
||
For example, the built-in assignment operators expect that
|
||
the left operand is an lvalue and that the right operand is a prvalue and yield an
|
||
lvalue as the result[.](#basic.lval-2.sentence-4)
|
||
|
||
User-defined operators are functions, and the categories of
|
||
values they expect and yield are determined by their parameter and return types[.](#basic.lval-2.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[3](#basic.lval-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L173)
|
||
|
||
[*Note [2](#basic.lval-note-2)*:
|
||
|
||
Historically, lvalues and rvalues were so-called
|
||
because they could appear on the left- and right-hand side of an assignment
|
||
(although this is no longer generally true);
|
||
glvalues are âgeneralizedâ lvalues,
|
||
prvalues are âpureâ rvalues,
|
||
and xvalues are âeXpiringâ lvalues[.](#basic.lval-3.sentence-1)
|
||
|
||
Despite their names, these terms apply to expressions, not values[.](#basic.lval-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#basic.lval-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L184)
|
||
|
||
[*Note [3](#basic.lval-note-3)*:
|
||
|
||
An expression is an xvalue if it is:
|
||
|
||
- [(4.1)](#basic.lval-4.1)
|
||
|
||
a move-eligible [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names"))
|
||
or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing")),
|
||
|
||
- [(4.2)](#basic.lval-4.2)
|
||
|
||
the result of calling a function, whether implicitly or explicitly,
|
||
whose return type is an rvalue reference to object type ([[expr.call]](expr.call "7.6.1.3 Function call")),
|
||
|
||
- [(4.3)](#basic.lval-4.3)
|
||
|
||
a cast to an rvalue reference to
|
||
object type ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7 Dynamic cast"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)")),
|
||
|
||
- [(4.4)](#basic.lval-4.4)
|
||
|
||
a subscripting operation with an xvalue array operand ([[expr.sub]](expr.sub "7.6.1.2 Subscripting")),
|
||
|
||
- [(4.5)](#basic.lval-4.5)
|
||
|
||
a class member access expression designating a non-static data member
|
||
of non-reference type
|
||
in which the object expression is an xvalue ([[expr.ref]](expr.ref "7.6.1.5 Class member access")), or
|
||
|
||
- [(4.6)](#basic.lval-4.6)
|
||
|
||
a .* pointer-to-member expression in which the first operand is
|
||
an xvalue and the second operand is a pointer to data member ([[expr.mptr.oper]](expr.mptr.oper "7.6.4 Pointer-to-member operators"))[.](#basic.lval-4.sentence-1)
|
||
|
||
In general, the effect of this rule is that named rvalue references are
|
||
treated as lvalues and unnamed rvalue references to objects are treated as
|
||
xvalues; rvalue references to functions are treated as lvalues whether named or not[.](#basic.lval-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#basic.lval-example-1)*: struct A {int m;};
|
||
A&& operator+(A, A);
|
||
A&& f();
|
||
|
||
A a;
|
||
A&& ar = static_cast<A&&>(a);
|
||
|
||
The expressions f(), f().m, static_cast<A&&>(a), and a + a are xvalues[.](#basic.lval-4.sentence-3)
|
||
|
||
The expression ar is an lvalue[.](#basic.lval-4.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
[5](#basic.lval-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L229)
|
||
|
||
The [*result*](#def:result,glvalue "7.2.1 Value category [basic.lval]") of a glvalue is the entity denoted by the expression[.](#basic.lval-5.sentence-1)
|
||
|
||
The [*result*](#def:result,prvalue "7.2.1 Value category [basic.lval]") of a prvalue
|
||
is the value that the expression stores into its context;
|
||
a prvalue that has type cv void has no result[.](#basic.lval-5.sentence-2)
|
||
|
||
A prvalue whose result is the value *V* is sometimes said to have or name the value *V*[.](#basic.lval-5.sentence-3)
|
||
|
||
The [*result object*](#def:result_object "7.2.1 Value category [basic.lval]") of a prvalue is the object initialized by the prvalue;
|
||
a prvalue that has type cv void has no result object[.](#basic.lval-5.sentence-4)
|
||
|
||
[*Note [4](#basic.lval-note-4)*:
|
||
|
||
Except when the prvalue is the operand of a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]"),
|
||
a prvalue of object type always has a result object[.](#basic.lval-5.sentence-5)
|
||
|
||
For a discarded prvalue that has type other than cv void,
|
||
a temporary object is materialized; see [[expr.context]](#expr.context "7.2.3 Context dependence")[.](#basic.lval-5.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[6](#basic.lval-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L246)
|
||
|
||
Whenever a glvalue appears as an operand of an operator that
|
||
requires a prvalue for that operand, the
|
||
lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), array-to-pointer ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")),
|
||
or function-to-pointer ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion")) standard conversions are
|
||
applied to convert the expression to a prvalue[.](#basic.lval-6.sentence-1)
|
||
|
||
[*Note [5](#basic.lval-note-5)*:
|
||
|
||
An attempt to bind an rvalue reference to an lvalue is not such a context; see [[dcl.init.ref]](dcl.init.ref "9.5.4 References")[.](#basic.lval-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [6](#basic.lval-note-6)*:
|
||
|
||
Because cv-qualifiers are removed from the type of an expression of
|
||
non-class type when the expression is converted to a prvalue, an lvalue
|
||
of type const int can, for example, be used where
|
||
a prvalue of type int is required[.](#basic.lval-6.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [7](#basic.lval-note-7)*:
|
||
|
||
There are no prvalue bit-fields; if a bit-field is converted to a
|
||
prvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), a prvalue of the type of the bit-field is
|
||
created, which might then be promoted ([[conv.prom]](conv.prom "7.3.7 Integral promotions"))[.](#basic.lval-6.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[7](#basic.lval-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L267)
|
||
|
||
Unless otherwise specified ([[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast")),
|
||
whenever a prvalue
|
||
that is not the result of the lvalue-to-rvalue conversion ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion"))
|
||
appears as an operand of an operator,
|
||
the [temporary materialization conversion](conv.rval "7.3.5 Temporary materialization conversion [conv.rval]") is
|
||
applied to convert the expression to an xvalue[.](#basic.lval-7.sentence-1)
|
||
|
||
[8](#basic.lval-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L275)
|
||
|
||
[*Note [8](#basic.lval-note-8)*:
|
||
|
||
The discussion of reference initialization in [[dcl.init.ref]](dcl.init.ref "9.5.4 References") and of
|
||
temporaries in [[class.temporary]](class.temporary "6.8.7 Temporary objects") indicates the behavior of lvalues
|
||
and rvalues in other significant contexts[.](#basic.lval-8.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[9](#basic.lval-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L282)
|
||
|
||
Unless otherwise indicated ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")),
|
||
a prvalue shall always have complete type or the void type;
|
||
if it has a class type or (possibly multidimensional) array of class type,
|
||
that class shall not be an abstract class ([[class.abstract]](class.abstract "11.7.4 Abstract classes"))[.](#basic.lval-9.sentence-1)
|
||
|
||
A glvalue shall not have type cv void[.](#basic.lval-9.sentence-2)
|
||
|
||
[*Note [9](#basic.lval-note-9)*:
|
||
|
||
A glvalue can have complete or incomplete non-void type[.](#basic.lval-9.sentence-3)
|
||
|
||
Class and array prvalues can have cv-qualified types; other prvalues
|
||
always have cv-unqualified types[.](#basic.lval-9.sentence-4)
|
||
|
||
See [[expr.type]](#expr.type "7.2.2 Type")[.](#basic.lval-9.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[10](#basic.lval-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L294)
|
||
|
||
An lvalue is [*modifiable*](#def:modifiable "7.2.1 Value category [basic.lval]") unless its type is const-qualified
|
||
or is a function type[.](#basic.lval-10.sentence-1)
|
||
|
||
[*Note [10](#basic.lval-note-10)*:
|
||
|
||
A program that attempts
|
||
to modify an object through a nonmodifiable lvalue or through an rvalue
|
||
is ill-formed ([[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators"), [[expr.post.incr]](expr.post.incr "7.6.1.6 Increment and decrement"), [[expr.pre.incr]](expr.pre.incr "7.6.2.3 Increment and decrement"))[.](#basic.lval-10.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[11](#basic.lval-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L303)
|
||
|
||
An object of dynamic type Tobj is[*type-accessible*](#def:type-accessible "7.2.1 Value category [basic.lval]") through a glvalue of type Tref if Tref is similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to:
|
||
|
||
- [(11.1)](#basic.lval-11.1)
|
||
|
||
Tobj,
|
||
|
||
- [(11.2)](#basic.lval-11.2)
|
||
|
||
a type that is the signed or unsigned type corresponding to Tobj, or
|
||
|
||
- [(11.3)](#basic.lval-11.3)
|
||
|
||
a char, unsigned char, or std::byte type[.](#basic.lval-11.sentence-1)
|
||
|
||
If a program attempts to access ([[defns.access]](defns.access "3.1 access"))
|
||
the stored value of an object through a glvalue
|
||
through which it is not type-accessible,
|
||
the behavior is undefined[.](#basic.lval-11.sentence-2)[42](#footnote-42 "The intent of this list is to specify those circumstances in which an object can or cannot be aliased.")
|
||
|
||
If a program invokes
|
||
a defaulted copy/move constructor or copy/move assignment operator
|
||
for a union of type U with a glvalue argument
|
||
that does not denote an object of type cv U within its lifetime,
|
||
the behavior is undefined[.](#basic.lval-11.sentence-3)
|
||
|
||
[*Note [11](#basic.lval-note-11)*:
|
||
|
||
In C, an entire object of structure type can be accessed, e.g., using assignment[.](#basic.lval-11.sentence-4)
|
||
|
||
By contrast, C++ has no notion of accessing an object of class type
|
||
through an lvalue of class type[.](#basic.lval-11.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[42)](#footnote-42)[42)](#footnoteref-42)
|
||
|
||
The intent of this list is to specify those circumstances in which an
|
||
object can or cannot be aliased[.](#footnote-42.sentence-1)
|
||
|
||
### [7.2.2](#expr.type) Type [[expr.type]](expr.type)
|
||
|
||
[1](#expr.type-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L335)
|
||
|
||
If an expression initially has the type âreference toTâ ([[dcl.ref]](dcl.ref "9.3.4.3 References"), [[dcl.init.ref]](dcl.init.ref "9.5.4 References")), the type is adjusted toT prior to any further analysis;
|
||
the value category of the expression is not altered[.](#expr.type-1.sentence-1)
|
||
|
||
Let X be the object or function denoted by the reference[.](#expr.type-1.sentence-2)
|
||
|
||
If a pointer to X would be valid in
|
||
the context of the evaluation of the expression ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")),
|
||
the result designates X;
|
||
otherwise, the behavior is undefined[.](#expr.type-1.sentence-3)
|
||
|
||
[*Note [1](#expr.type-note-1)*:
|
||
|
||
Before the lifetime of the reference has started or after it has ended,
|
||
the behavior is undefined (see [[basic.life]](basic.life "6.8.4 Lifetime"))[.](#expr.type-1.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[2](#expr.type-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L351)
|
||
|
||
If a prvalue initially has the type âcv Tâ, whereT is a cv-unqualified non-class, non-array type, the type of
|
||
the expression is adjusted to T prior to any further analysis[.](#expr.type-2.sentence-1)
|
||
|
||
[3](#expr.type-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L356)
|
||
|
||
The [*composite pointer type*](#def:composite_pointer_type "7.2.2 Type [expr.type]") of
|
||
two operands p1 andp2 having types T1 and T2, respectively, where at least one is a
|
||
pointer or pointer-to-member type orstd::nullptr_t, is:
|
||
|
||
- [(3.1)](#expr.type-3.1)
|
||
|
||
if both p1 and p2 are null pointer constants,std::nullptr_t;
|
||
|
||
- [(3.2)](#expr.type-3.2)
|
||
|
||
if either p1 or p2 is a null pointer constant, T2 or T1,
|
||
respectively;
|
||
|
||
- [(3.3)](#expr.type-3.3)
|
||
|
||
if T1 or T2 is âpointer to *cv1* voidâ and the
|
||
other type is âpointer to *cv2* Tâ,
|
||
where T is an object type or void,
|
||
âpointer to *cv12* voidâ,
|
||
where *cv12* is the union of *cv1* and *cv2*;
|
||
|
||
- [(3.4)](#expr.type-3.4)
|
||
|
||
if T1 or T2 is âpointer to noexcept functionâ and the
|
||
other type is âpointer to functionâ, where the function types are otherwise the same,
|
||
âpointer to functionâ;
|
||
|
||
- [(3.5)](#expr.type-3.5)
|
||
|
||
if T1 is âpointer to C1â and T2 is âpointer toC2â, where C1 is reference-related to C2 or C2 is
|
||
reference-related to C1 ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")),
|
||
the qualification-combined type ([[conv.qual]](conv.qual "7.3.6 Qualification conversions"))
|
||
of T1 and T2 or the qualification-combined type of T2 and T1,
|
||
respectively;
|
||
|
||
- [(3.6)](#expr.type-3.6)
|
||
|
||
if T1 or T2 is
|
||
âpointer to member of C1 of type functionâ,
|
||
the other type is
|
||
âpointer to member of C2 of type noexcept functionâ, andC1 is reference-related to C2 orC2 is reference-related to C1 ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")),
|
||
where the function types are otherwise the same,
|
||
âpointer to member of C2 of type functionâ or
|
||
âpointer to member of C1 of type functionâ, respectively;
|
||
|
||
- [(3.7)](#expr.type-3.7)
|
||
|
||
if T1 is
|
||
âpointer to member of C1 of type *cv1* Uâ andT2 is
|
||
âpointer to member of C2 of type *cv2* Uâ,
|
||
for some non-function type U,
|
||
where C1 is
|
||
reference-related to C2 or C2 is reference-related toC1 ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")), the qualification-combined type of T2 and T1 or the qualification-combined type
|
||
of T1 and T2, respectively;
|
||
|
||
- [(3.8)](#expr.type-3.8)
|
||
|
||
if T1 and T2 are similar types ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")), the qualification-combined type of T1 andT2;
|
||
|
||
- [(3.9)](#expr.type-3.9)
|
||
|
||
otherwise, a program that necessitates the determination of a
|
||
composite pointer type is ill-formed[.](#expr.type-3.sentence-1)
|
||
|
||
[*Example [1](#expr.type-example-1)*: typedef void *p;typedef const int *q;typedef int **pi;typedef const int **pci;
|
||
|
||
The composite pointer type of p and q is âpointer to const voidâ; the
|
||
composite pointer type of pi and pci is âpointer to const pointer toconst intâ[.](#expr.type-3.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
### [7.2.3](#expr.context) Context dependence [[expr.context]](expr.context)
|
||
|
||
[1](#expr.context-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L438)
|
||
|
||
In some contexts, [*unevaluated operands*](#def:unevaluated_operand "7.2.3 Context dependence [expr.context]") appear ([[expr.prim.req.simple]](expr.prim.req.simple "7.5.8.2 Simple requirements"), [[expr.prim.req.compound]](expr.prim.req.compound "7.5.8.4 Compound requirements"), [[expr.typeid]](expr.typeid "7.6.1.8 Type identification"), [[expr.sizeof]](expr.sizeof "7.6.2.5 Sizeof"), [[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"), [[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator"), [[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers"), [[temp.pre]](temp.pre "13.1 Preamble"), [[temp.concept]](temp.concept "13.7.9 Concept definitions"))[.](#expr.context-1.sentence-1)
|
||
|
||
An unevaluated operand is not evaluated[.](#expr.context-1.sentence-2)
|
||
|
||
[*Note [1](#expr.context-note-1)*:
|
||
|
||
In an unevaluated operand, a non-static class member can be
|
||
named ([[expr.prim.id]](expr.prim.id "7.5.5 Names")) and naming of objects or functions does not, by
|
||
itself, require that a definition be provided ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#expr.context-1.sentence-3)
|
||
|
||
An unevaluated operand is considered a [full-expression](intro.execution#def:full-expression "6.10.1 Sequential execution [intro.execution]")[.](#expr.context-1.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[2](#expr.context-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L458)
|
||
|
||
In some contexts, an expression only appears for its side effects[.](#expr.context-2.sentence-1)
|
||
|
||
Such an
|
||
expression is called a [*discarded-value expression*](#def:discarded-value_expression "7.2.3 Context dependence [expr.context]")[.](#expr.context-2.sentence-2)
|
||
|
||
The [array-to-pointer](conv.array "7.3.3 Array-to-pointer conversion [conv.array]") and [function-to-pointer](conv.func "7.3.4 Function-to-pointer conversion [conv.func]") standard conversions are not
|
||
applied[.](#expr.context-2.sentence-3)
|
||
|
||
The [lvalue-to-rvalue](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]") conversion is applied
|
||
if and only if
|
||
the expression is a glvalue of volatile-qualified type and it is one of the
|
||
following:
|
||
|
||
- [(2.1)](#expr.context-2.1)
|
||
|
||
( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ), where[*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is one of these expressions,
|
||
|
||
- [(2.2)](#expr.context-2.2)
|
||
|
||
[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") ([[expr.prim.id]](expr.prim.id "7.5.5 Names")),
|
||
|
||
- [(2.3)](#expr.context-2.3)
|
||
|
||
[*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing")),
|
||
|
||
- [(2.4)](#expr.context-2.4)
|
||
|
||
[subscripting](expr.sub "7.6.1.2 Subscripting [expr.sub]"),
|
||
|
||
- [(2.5)](#expr.context-2.5)
|
||
|
||
[class member access](expr.ref "7.6.1.5 Class member access [expr.ref]"),
|
||
|
||
- [(2.6)](#expr.context-2.6)
|
||
|
||
[indirection](expr.unary.op#def:indirection "7.6.2.2 Unary operators [expr.unary.op]"),
|
||
|
||
- [(2.7)](#expr.context-2.7)
|
||
|
||
[pointer-to-member operation](expr.mptr.oper "7.6.4 Pointer-to-member operators [expr.mptr.oper]"),
|
||
|
||
- [(2.8)](#expr.context-2.8)
|
||
|
||
[conditional expression](expr.cond "7.6.16 Conditional operator [expr.cond]") where both the second and the
|
||
third operands are one of these expressions, or
|
||
|
||
- [(2.9)](#expr.context-2.9)
|
||
|
||
[comma expression](expr.comma "7.6.20 Comma operator [expr.comma]") where the right operand is one of
|
||
these expressions[.](#expr.context-2.sentence-4)
|
||
|
||
[*Note [2](#expr.context-note-2)*:
|
||
|
||
Using an overloaded operator causes a function call; the
|
||
above covers only operators with built-in meaning[.](#expr.context-2.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
The temporary materialization conversion ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion")) is applied
|
||
if the (possibly converted) expression is a prvalue of object type[.](#expr.context-2.sentence-6)
|
||
|
||
[*Note [3](#expr.context-note-3)*:
|
||
|
||
If the original expression is an lvalue of class type,
|
||
it must have a volatile copy constructor to initialize the temporary object
|
||
that is the result object of the temporary materialization conversion[.](#expr.context-2.sentence-7)
|
||
|
||
â *end note*]
|
||
|
||
The expression is evaluated and its result (if any) is discarded[.](#expr.context-2.sentence-8)
|