Topic: Temporary object's lifetime and Full-expression
Author: stkim@yujinrobot.com ("Kim, Seungtai")
Date: Fri, 22 Apr 2005 19:44:48 GMT Raw View
There were some discussion about parameter passing of the temporary object
at the han.comp.lang.c++. The original question was simple why bellow code
dose not work.
foo( &A() );
Yes. Clear. It's illegal use of operator & that requires the lvalue which
the tempporary dose not return. And there another question was followed.
"What about this case? Is it legel and dose it produce well-defined behavior?"
struct A {
A& me() { return *this; }
};
void foo(const A* a);
...
foo( &A().me() );
I said it's not. It will make the undefined behavior. The reason is that
the temporary object will be destroyed at the point of immediately after
calling function foo. Therefore foo will get the dangling pointer. It's
illegal use of invalid pointer.
But the others assist the opposite opinion that the temporary object
will not be destroyed until the completion of the full expression
calling foo.
My opinion comes from the definition of the temporary object's lifetime
and the full-expression. 12.2/p3 states the general rule for lifetime of
the temporary object.
12.2/p3
Temporary objects are destroyed as the last step in evaluating
the full-expression (1.9) that (lexically) contains the point
where they were created.
And 1.9/p12 states the definition of the full-expression.
1.9/p12
A full-expression is an expression that is not a subexpression
of another expression.
And 1.9/p13 describes the function call is full expression, also.
1.9/p13
... the function call is a full-expression.
In this point, there can be two different but ciritical interpretations
whether the function call in an expression is a sub-expression
or not it's an independent full expression.
- The function call is sub-expression. It's explicitly included in
the other expression. So, the temporary object should not be destroyed
until after evaluating full expression that contains the function call.
Therefore OP's above code is legal and produce well-defined behavior.
- The function call is full expression that it is independent
from the expression containing the function call. For that reason, the
temporary object shold be destroyed immediately after calling function.
Hance, above code will make UB.
Which opinion is correct?
I have the more questions if we assume that the function call is a
sub-expression of the other expression.
1. Why dose the bellow sentance exist?
12.4/p5
... A temporary bound to a reference parameter in a function
call(5.2.2) persists until the completion of the full
expression containing the call. ...
If function call is a sub-expression, it's not required. Always
the temporary object survives until the completion of the full
expression containing the function call. Why it needed?
Am I something wrong and mis-interpretation?
2. Why dose the 1.9/p13 emphasize "function call is a full expression."
twice. If we think about that there are return of the function,
it's clear that the function call alone could not be the full-expression, always.
For example, in a "a = f( x ) ;", f( x ) is just a sub-expression,
not a full-expression. Another case, even f returns void and in
expression of "f( x );", the final expression is "void", not a function
call. For that reason, a function call itself can not be the full-expression.
And the explanation should be just a "expression" not a "full expression".
Is it overlooking?
3. Last one. Is there full expression in the C++ program if the function
call is just a sub-expression? I think there isn't. If we define the
function call makes the relation of the sub-expression, all the reacheable
functions comes from the main and creation realated functions for the
static obejcts. And they are called by execution environment. So, there is
no full-expression. Is it true?
Thanks in advice.
--
S Kim <stkim@yujinrobot.com>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@lhup.edu (John Potter)
Date: Sat, 23 Apr 2005 01:21:22 GMT Raw View
On Fri, 22 Apr 2005 19:44:48 GMT, stkim@yujinrobot.com ("Kim, Seungtai")
wrote:
> "What about this case? Is it legel and dose it produce well-defined behavior?"
> struct A {
> A& me() { return *this; }
> };
> void foo(const A* a);
> ...
> foo( &A().me() );
> I said it's not. It will make the undefined behavior. The reason is that
> the temporary object will be destroyed at the point of immediately after
> calling function foo. Therefore foo will get the dangling pointer. It's
> illegal use of invalid pointer.
No.
> But the others assist the opposite opinion that the temporary object
> will not be destroyed until the completion of the full expression
> calling foo.
Yes.
The major problem in all that follows is quoting out of context.
> My opinion comes from the definition of the temporary object's lifetime
> and the full-expression. 12.2/p3 states the general rule for lifetime of
> the temporary object.
> 12.2/p3
> Temporary objects are destroyed as the last step in evaluating
> the full-expression (1.9) that (lexically) contains the point
> where they were created.
Fine.
> And 1.9/p12 states the definition of the full-expression.
>
> 1.9/p12
> A full-expression is an expression that is not a subexpression
> of another expression.
Fine.
> And 1.9/p13 describes the function call is full expression, also.
> 1.9/p13
> ... the function call is a full-expression.
No, you are out of context. The context is initialization which
contains no syntactic expression yet is treated as a full-expression
consisting of a function call.
struct S { S (int); };
void f () {
S s1(1); // No expression, but treated as function call
S s2 = 2; // Same
}
The text does not say that all function calls are full-expressions. It
says that these two cases are full-expression function calls.
> In this point, there can be two different but ciritical interpretations
> whether the function call in an expression is a sub-expression
> or not it's an independent full expression.
Not if you read everything and not just part.
> - The function call is sub-expression. It's explicitly included in
> the other expression. So, the temporary object should not be destroyed
> until after evaluating full expression that contains the function call.
> Therefore OP's above code is legal and produce well-defined behavior.
Yes.
> - The function call is full expression that it is independent
> from the expression containing the function call. For that reason, the
> temporary object shold be destroyed immediately after calling function.
> Hance, above code will make UB.
No.
> I have the more questions if we assume that the function call is a
> sub-expression of the other expression.
> 1. Why dose the bellow sentance exist?
>
> 12.4/p5
This is 12.2/5.
> ... A temporary bound to a reference parameter in a function
> call(5.2.2) persists until the completion of the full
> expression containing the call. ...
You are again missing the major point. A temporary bound to a reference
normally has the its lifetime extended to that of the reference. This
is an exception to that rule because the temporary outlives the
reference which terminates upon return.
> If function call is a sub-expression, it's not required. Always
> the temporary object survives until the completion of the full
> expression containing the function call. Why it needed?
To emphasize that it outlives the reference which is the subject of
this paragraph.
> 2. Why dose the 1.9/p13 emphasize "function call is a full expression."
> twice.
See above. It is talking about two special cases where a non-expression
syntax is treated as a full-expression.
John
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Mon, 25 Apr 2005 01:21:52 GMT Raw View
"Kim, Seungtai" wrote:
<snip>
> "What about this case? Is it legel and dose it produce well-defined behavior?"
>
> struct A {
> A& me() { return *this; }
> };
>
> void foo(const A* a);
>
> ...
> foo( &A().me() );
>
> I said it's not. It will make the undefined behavior. The reason is that
> the temporary object will be destroyed at the point of immediately after
> calling function foo. Therefore foo will get the dangling pointer. It's
> illegal use of invalid pointer.
>
> But the others assist the opposite opinion that the temporary object
> will not be destroyed until the completion of the full expression
> calling foo.
This is correct.
> My opinion comes from the definition of the temporary object's lifetime
> and the full-expression. 12.2/p3 states the general rule for lifetime of
> the temporary object.
>
> 12.2/p3
> Temporary objects are destroyed as the last step in evaluating
> the full-expression (1.9) that (lexically) contains the point
> where they were created.
>
> And 1.9/p12 states the definition of the full-expression.
>
> 1.9/p12
> A full-expression is an expression that is not a subexpression
> of another expression.
>
> And 1.9/p13 describes the function call is full expression, also.
>
> 1.9/p13
> ... the function call is a full-expression.
<snip>
First, that's a note, so it's not normative[*]. Second, it describes
implicit function calls to constructors, not function calls in
general. In an expression-statement, the full-expression is the whole
of the statement aside from the terminating semi-colon.
[*] It's supposed to provide clarification. Unfortunately a lot of
notes actually provide distraction.
--
Ben Hutchings
If the facts do not conform to your theory, they must be disposed of.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]