Description
Originally posted by @xmh0511 in #4837 (comment) and #4798.
Currently [dcl.constexpr] p10 says that in the defintion of a constexpr
variable, the "full-expression of the initialization" shall be a constant expression. And according to [expr.const] p1, a constant expression is also an expression.
However, the "full-expression of the initialization" of a variable may be not an expression. It seems that "full-expression of the initialization" of a variable corresponds to the case specified in [intro.execution] p5 (5.4): an init-declarator (or a mem-initializer) is not an expression.
Note that [expr.const] p2 (2.2) uses "when interpretd as", which may imply that the "full-expression of its initialization" is not itself an expression.
Perhaps there are some contradictions currently, and we should clarify that
- the full-expression of initialization of a variable is not itself an expression (and hence not a constant expression), and
- how to "interpret" an initialization as an expression.
Activity
xmh0511 commentedon Sep 1, 2021
Actually, the concern in #4798 arises from certain examples
In this full-expression of the initialization, it will comprise the call of
#1
, the default constructor call ofClass
, and the destructor call ofClass
at the end of that full-expression and that full-expression of the initialization should be aglvaue
constant expression for this purpose.The purpose of "when interpreted as constant-expression" is that we give a hypothetical grammar meaning to "full-expression of the initialization" that should have been not an expression on grammar, in order to make all semantic rules that apply to the expression on grammar apply to "full-expression of the initialization". “full-expression ” works for collecting these separated expressions.
We lack the wording about the storage duration of the temporary variable in this full-expression of initialization, as specified in #4840.
xmh0511 commentedon Sep 2, 2021
BTW, since @jensmaurer in #4837 has answered like this
the full-expression of the initialization is the exception, I try to adjust the example above that comment as the following
The specifier constexpr in the variable declaration requires that the full-expression of the initialization is a constant expression, even though it is not a syntactical expression, and we impose it to interpret as a constant-expression that is syntactical, however, what's the value category of this hypothetical constant-expression? It seems to lack to expound. I think the value category is significant here since a constant expression is either a glvalue or prvalue core constant expression, we require to do further checks according to their value category.
frederick-vs-ja commentedon Sep 5, 2021
Proposed changes:
Change [dcl.constexpr] p10:
from
to
Change [expr.const] p2 (2.2):
from
to
@xmh0511 @jensmaurer How do you think about these changes? Is a CWG issue needed?
Add following contents to show how to transform the constraints:
frederick-vs-ja commentedon Sep 5, 2021
Oh, initialization of an object that is neither variable nor temporary object can also satisfy these constraints, and such initialization can appear in constant evaluation since C++20.
Should we also specify that such an object is also constant-initialized? Is a (separated) CWG needed?
xmh0511 commentedon Sep 6, 2021
I would say "full-expression of its initialization" is not an expression of the grammar, whether a construct is a core constant expression or not is first based on it is an expression of the grammar.
IMO, change the following normative rule
to be a note may be radical but it seems plausible. I think for any initialization of an object, the destructor call cannot appear in that full-expression, even though the object is temporary whose lifetime has been extended or not.
frederick-vs-ja commentedon Sep 6, 2021
I think the updated wording can show how to transform the constraints of a core constant expression.
xmh0511 commentedon Feb 8, 2022
@jensmaurer @frederick-vs-ja
After thinking more about this issue. I think the point of clarifying this issue is:
Consider a slightly complex example:
First, what is the full-expression of the initialization at
#1
? Is the full-expression the init-declarator, as per [intro.execution-5.4]? According to [intro.execution] p5And [dcl.init.ref#5.4.1]
It seems that the language construct init-declarator can be considered as an expression for purposes of the definition of a full-expression. Name the language construct(init-declarator) as the expression
E
, sinceA::A(int)
is implicitly called byE
, thus the call ofA::A(int)
is a subexpression ofE
. [intro.execution] p5 also saysAccording to [dcl.init.ref#5.3]
The temporary conversion is a part of the full-expression. Also, according to [expr.const] p2.2
we can conclude that:
E
is interpreted as a constant-expression andE
is a full-expression. The constituents ofE
comprise:the call of A::A(int)
and temporary materialization conversionIt is my interpretation of full-expression of initialization.
frederick-vs-ja commentedon Mar 17, 2025
CWG3009 should also cover this.
[-][dcl.constexpr] A full-expression of initialization of a variable may be not an expression[/-][+][dcl.constexpr] A full-expression of initialization of a variable may be not an expression CWG3009[/+]