4

Consider this example

#include <iostream>
struct A{
   A(){
       std::cout<<"A ctor\n";
   }
   ~A(){
       std::cout<<"A dtor\n";
   }
};
int fun(A const&){
    std::cout<<"abc\n";
    return 0;
}
void show(double, int){
    std::cout<<"show\n";
}
int main() {
   show(0,fun(A{}));  // #1
}

According to the result, it is observable that the temporary object is destroyed at the completion of #1. According to [class.temporary] p6

The exceptions to this lifetime rule are:

  • A temporary object bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.

I wonder why is show(0,fun(A{})); the full-expression of fun(A{})? According to [basic.exec#intro.execution-5]

A full-expression is

-[...]

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

show(0,fun(A{})); is a full-expression, however, the function call fun(A{}) that is an argument of the function call of show is not a subexpression of the enclosing function call(if explicitly specified arguments are not operands of a function call). The definition of part of a full-expression is also not clear in the standard.

I have the following concerns:

  • Are arguments considered to be operands of the function call?

the answers in C standard seems to say they are not

  • What is the part of a full-expression?
xmh0511
  • 7,010
  • 1
  • 9
  • 36
  • @Scheff'sCat I didn't ask whether a function call is an expression or not. The answer is it is an expression. I'm asking whether the **arguments** of a function call are **operands** of that function call(**expression**), which determines whether arguments are subexpressions of that function call, which in turn, determines whether an expression is a full-expression or not. – xmh0511 Oct 08 '21 at 05:28
  • Sorry, I should've kept my fingers... In practice the full expression ends where the semicolon appears. That might be not be fully correct but works in daily business. :-( I found "an expression... ...that is not otherwise part of a full-expression" quite clear. – Scheff's Cat Oct 08 '21 at 05:30
  • @Scheff'sCat That may be an informal explanation of **full-expression**. I'm looking forward to the formal explanation of **part of a full-expression** as well as whether the arguments are operands. – xmh0511 Oct 08 '21 at 05:32
  • But the Standard is written in natural language. At some point it must defer to common sense and understanding of the written words. If every phrase or word needs a formal definition, it would never find an end. "Not a sub-expression of another expression" is as formal as it can get. – j6t Oct 08 '21 at 05:38
  • @j6t It is exactly asking whether an argument of a function call is the operand of that expression, which determines whether the argument is a subexpression of that function call. Again, how do you understand the phrase "part of a full-expression"? – xmh0511 Oct 08 '21 at 05:41
  • But of course there is no "separation" of expressions between the function call and its arguments. Look at the syntax definition: a function call is a *postfix-expression*, and that is reachable from and recurses into an *expression*. – j6t Oct 08 '21 at 05:47
  • Considering that a function call is an Id expression followed by a postfix operator, I don't see why the post-fix operator (the brackets with optional operands separated by commas) should be considered different from any other operator (except for its specific semantic like any other operator). – Scheff's Cat Oct 08 '21 at 05:49
  • _5.2.2: A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function._ (from N3797) Next step: What are "initializer-clauses"? AFAIS in _8.5. Initializers_, it's part of a recursive definition which boils down to expressions in all cases (if not empty). – Scheff's Cat Oct 08 '21 at 05:57
  • @Scheff'sCat Yes, arguments are indeed **expressions**, however, **subexpression** has an explicit specification, which is defined in [basic.exec#intro.execution-3](https://timsong-cpp.github.io/cppwp/n4861/basic.exec#intro.execution-3). To be a subexpression, it shall satisfy one bullet in that list. – xmh0511 Oct 08 '21 at 06:01
  • I found arguments at the beginning in _1.3. Terms and definitions_. Looking for "operand" I ended up in a Note: which comes directly after your 2nd citation: _Note: in some contexts, such as unevaluated operands, a syntactic subexpression is considered a full-expression (Clause 5). —end note ]_ I give up... – Scheff's Cat Oct 08 '21 at 06:08
  • @Scheff'sCat Although it is irrelevant with this question, I have to say Isn't that note covered by [basic.exec#intro.execution-5.1]? *A full-expression is an unevaluated operand,* – xmh0511 Oct 08 '21 at 06:15
  • The arguments of a function call expression are operands. I'm not sure why you think they aren't. We should interpret the standard in a way that makes sense, instead of going out of our way to use definitions of words that make the standard seem absurd. – Brian Bi Oct 02 '22 at 00:02

0 Answers0