cplusplus / CWG

Core Working Group
24 stars 7 forks source link

[intro.execution] p5 full-expression vs. expression #460

Open xmh0511 opened 1 year ago

xmh0511 commented 1 year ago

Full name of submitter (unless configured in github; will be published with the issue): Jim X

It seems that a full-expression is a set of grammar expressions or non-grammar expressions(i.e. implicitly function call expressions). However, a full-expression is defined as not necessarily an expression, per [intro.execution] p5

A full-expression is

  • [...]
  • an init-declarator ([dcl.decl]) or a mem-initializer ([class.base.init]), including the constituent expressions of the initializer,

However, somewhere in this document, we require a full-expression to be an expression to have a value category, for example, [dcl.constexpr] p6

In any constexpr variable declaration, the full-expression of the initialization shall be a constant expression ([expr.const]).

A constant expression is an expression that is defined by [expr.const] p13

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints

Anyway, only expression can it have a value category. Furthermore, the determination of a full-expression is significant for defining the destruction of a temporary object.

Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created.

Suggested Resolution

Clearly define what a full-expression is. Is it a collection of evaluated expressions? Define the value category of a full-expression when we require it to have a value category in the rules. Moreover, define how a full-expression is determined from.

frederick-vs-ja commented 1 year ago

I think only [dcl.constexpr] p6 is broken - it's currently requiring something that is not an expression to be an expression.

xmh0511 commented 1 year ago

Given a concrete example:

struct B{
    constexpr ~B(){}  // #1
};
struct A{
    constexpr A(const B&){}
    constexpr ~A(){}
};
int main(){
    constexpr A a = A(B{});
}

In this example, we actually want the evaluation of the construction of A and the destruction of B to satisfy the requirements of the core constant expression, hence, we use the utterance that the full-expression of the initialization shall be a constant expression, which includes the check of such two evaluations. However, what is the value category of the full-expression, which is not an expression?

In contrast, if we change #1 to ~B(){}, which will make the full-expression not a constant expression.

jensmaurer commented 1 year ago

A full-expression need not be an expression. [dcl.constexpr] p6 should say something else, I think.

xmh0511 commented 1 year ago

A full-expression need not be an expression. [dcl.constexpr] p6 should say something else, I think.

That means a full-expression is the specified grammar component listed in the list of [intro.execution] p5. Incidentally, we still didn't specify which expressions are lexically included by a full-expression(i.e. which expressions are part of a full-expression), which is https://github.com/cplusplus/draft/issues/6562.

Which expressions are (lexically)part of a full-expression is unclear, unlike we clearly define what constituent expressions of an expression

frederick-vs-ja commented 1 year ago

Incidentally, we still didn't specify which expressions are lexically included by a full-expression(i.e. which expressions are part of a full-expression), which is cplusplus/draft#6562.

The meaning of "lexically included/contained" should already be clear in plain English.

The issue I see in cplusplus/draft#6562 is that an implicit conversion, including temporary materialization, is not itself a lexical thing, and thus the lexically containing relationship doesn't work.

xmh0511 commented 1 year ago

Incidentally, we still didn't specify which expressions are lexically included by a full-expression(i.e. which expressions are part of a full-expression), which is cplusplus/draft#6562.

The meaning of "lexically included/contained" should already be clear in plain English.

The issue I see in cplusplus/draft#6562 is that an implicit conversion, including temporary materialization, is not itself a lexical thing, and thus the lexically containing relationship doesn't work.

Implicit conversion is lexically contained by a full-expression, this concept is used to playing a role in [expr.const].

frederick-vs-ja commented 1 year ago

Implicit conversion is lexically contained by a full-expression, this concept is used to playing a role in [expr.const].

Implicit conversion is always contained by some full-expression, but it's arguable whether we can say "lexically".

There's a issue in the relevant part of [expr.const] similar to that in [dcl.constexpr] p6: it's unclear how to interpret something that is not an expression as a constant-expression (which is an expression).