C++ 17 full-expression standard definition
Asked Answered
E

0

3

This paragraph from the C++ 17 standard draft states, among others, that:

A full-expression is:

-an unevaluated operand,

-a constant-expression ([expr.const]),

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

-an invocation of a destructor generated at the end of the lifetime of an object other than a temporary object, or

-an expression that is not a subexpression of another expression and that is not otherwise part of a full-expression.

If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition. [...]

struct S {

   S(int i): I(i) { }       // full-expression is initialization of I

   int& v() { return I; }
   ~S() noexcept(false) { }
private:
   int I;
};

S s1(1);                   // **full-expression is call of S​::​S(int)**

For the rest of this post I will refer to a "language construct defined to produce an implicit call of a function" simply as "construct".

I have several questions related to the quoted paragraph:

  1. Why is this passage ("and that is not otherwise part of a full-expression") mentioned? The only reasons I can think of are: a "construct" containing an expression (true expression, not the definition used in this paragraph, which considers "constructs" as expressions) that, otherwise, would be regarded as a full-expression or a "construct" containing another "construct", which, similarly, on its own would be considered as a full-expression. Are these reasons correct? If so, I would appreciate some concrete examples.

  2. What are some examples of "constructs"? I know that the initialization of an object could be one (because of the implicit call to the constructor), but the third dot of the paragraph ("an init-declarator ([dcl.decl])) explicitly considers it as a full-expression. Also, using the new operator means implicitly calling two functions (one for allocating the space and afterwards the constructor), but a new expression is an expression on its own.

  3. Why for the construct: "S s1(1)" is it said that the full-expression is the call to the constructor "S::S(int)"? Why isn't the full-expression the construct itself?

Exposition answered 8/8, 2017 at 19:10 Comment(8)
There's another example further down: B b[2] = { B(), B() }; // full-expression is the entire initialization including the destruction of temporaries. I think that phrase refers to this case. You have init-declarator that's not, technically, an expression, and so parts of it are not, technically, subexpressions.Hindi
You are referring to question number 1, correct? Therefore the example that you showed of a init-declarator falls into the first category that I mentioned, that of "constructs containing an expression...". Did I understand this correctly?Exposition
Yes, I'm referring to question 1. You asked for concrete examples - there's one right there in the text of the standard. I'm not quite sure what more you are looking for.Hindi
3 Maybe because the intent is for S s1(1), s2(2); to represent two full expressions.Hindi
The example that you've given: S s1(1), s2(2); represents an entire construct (real meaning, not the one used in this question), but it does not require an implicit function call, because the implicit function calls are made by its sub-constructs: S s1(1) and (S) s2(2)? Therefore the outer construct is not a full-expression, but the inner constructs are? Is this one way to interpret it?Exposition
s1(1) and s2(2) are init-declarators within the meaning of [dcl.decl]. They are therefore full expressions, per the third bullet of the paragraph you cite. They are not, however, expressions within the meaning of [expr] (1 and 2 are; but they are not full-exressions because they are "otherwise part of a full-expression").Hindi
Re: 2, I must admit I can't think of an example of a language construct that a) would produce a function call, but b) is not itself an expression. I'm sure it's due to lack of imagination on my part.Hindi
I still believe that saying the full-expression of S s1(1) is the call to S::S(int) is a contradiction. The paragraph says that a "construct" is to be considered as an expression in this context. Furthermore, this construct is not part of an outer full-expression, therefore, in my opinion, the entire construct should be considered as the full-expression. Maybe it underlines the implicit function call.Exposition

© 2022 - 2024 — McMap. All rights reserved.