Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lifetime of temporary objects

2 views
Skip to first unread message

Old Wolf

unread,
Dec 5, 2003, 7:56:46 AM12/5/03
to
Assuming:

#include <string>
std::string get_string();
int func(const char *p);

are the following valid (correct, well-defined, specified,
advisable, standard, etc. etc.):

char c = *get_string().c_str();

func(get_string().c_str());

Note that in the latter, there is a sequence-point after the
last use of the object, so if the temporary object is deleted
at that sequence point, then func() will have some problems.

I saw an earlier thread on a similar topic which mentioned
"full-expression"s but it did not explain this in enough detail.

Finally, a "cousin" to the above question: is there any
guaranteed order of calling each get_string() in the following:

get_string().append(get_string())

Thanks,
Matt.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Dhruv

unread,
Dec 5, 2003, 6:03:40 PM12/5/03
to
On Fri, 05 Dec 2003 07:56:46 -0500, Old Wolf wrote:

[...]


> Finally, a "cousin" to the above question: is there any
> guaranteed order of calling each get_string() in the following:
>
> get_string().append(get_string())
>

I don't think so, an implemenetation may call it in any order.


Regards,
-Dhruv.

Ben Hutchings

unread,
Dec 5, 2003, 6:12:12 PM12/5/03
to
Old Wolf wrote:
> Assuming:
>
> #include <string>
> std::string get_string();
> int func(const char *p);
>
> are the following valid (correct, well-defined, specified,
> advisable, standard, etc. etc.):
>
> char c = *get_string().c_str();
>
> func(get_string().c_str());
>
> Note that in the latter, there is a sequence-point after the
> last use of the object, so if the temporary object is deleted
> at that sequence point, then func() will have some problems.

Temporaries are destroyed after evaluation of the full expression,
except that the lifetime of a temporary may be extended if a local
reference-to-const is bound directly to it.

> I saw an earlier thread on a similar topic which mentioned
> "full-expression"s but it did not explain this in enough detail.

A full expression is an expression that is not part of another
expression. The last line of the above code includes all these
expressions:

- get_string
- get_string()
- get_string().c_str
- get_string().c_str()
- func(get_string().c_str())

of which the last is the full expression

> Finally, a "cousin" to the above question: is there any
> guaranteed order of calling each get_string() in the following:
>
> get_string().append(get_string())

No.

Raoul Gough

unread,
Dec 5, 2003, 6:16:43 PM12/5/03
to
old...@inspire.net.nz (Old Wolf) writes:

> Assuming:
>
> #include <string>
> std::string get_string();
> int func(const char *p);
>
> are the following valid (correct, well-defined, specified,
> advisable, standard, etc. etc.):
>
> char c = *get_string().c_str();

I assume you meant:

char *c = get_string().c_str();

to make the question interesting.

>
> func(get_string().c_str());
>
> Note that in the latter, there is a sequence-point after the
> last use of the object, so if the temporary object is deleted
> at that sequence point, then func() will have some problems.
>
> I saw an earlier thread on a similar topic which mentioned
> "full-expression"s but it did not explain this in enough detail.

Anything beyond the next semicolon is outside of the "full containing
expression", so your string (and the storage it manages for the
c_str() call) will be destroyed before calling func.

>
> Finally, a "cousin" to the above question: is there any
> guaranteed order of calling each get_string() in the following:
>
> get_string().append(get_string())

No, the ordering is not specified. The standard says the following
(5.2.2/8):

"The order of evaluation of arguments is unspecified. All side
effects of argument expression evaluations take effect before the
function is entered. The order of evaluation of the postfix
expression and the argument expression list is unspecified."

In this case, the postfix expression includes your first get_string()
call.

--
Raoul Gough.
export LESS='-X'

James Kanze

unread,
Dec 6, 2003, 8:53:44 PM12/6/03
to
old...@inspire.net.nz (Old Wolf) writes:

|> Assuming:

|> #include <string>
|> std::string get_string();
|> int func(const char *p);

|> are the following valid (correct, well-defined, specified,
|> advisable, standard, etc. etc.):

|> char c = *get_string().c_str();

Valid.

|> func(get_string().c_str());

Maybe. It depends on what func does with the pointer.

|> Note that in the latter, there is a sequence-point after the last
|> use of the object, so if the temporary object is deleted at that
|> sequence point, then func() will have some problems.

Sequence points don't have anything to do with the lifetime of
temporaries. Temporaries persist until the end of the full expression;
until the ';', in this case. There is no problem if func uses the
pointer. If func saves it somewhere for later use, after the return
from func, there is a real problem.

|> I saw an earlier thread on a similar topic which mentioned
|> "full-expression"s but it did not explain this in enough detail.

A full expression is an expression which isn't part of any other
expression. I don't know what more there is to explain.

|> Finally, a "cousin" to the above question: is there any
|> guaranteed order of calling each get_string() in the following:

|> get_string().append(get_string())

None whatsoever.

--
James Kanze mailto:ka...@gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

Raoul Gough

unread,
Dec 8, 2003, 5:47:29 PM12/8/03
to
James Kanze <ka...@alex.gabi-soft.fr> writes:

> old...@inspire.net.nz (Old Wolf) writes:
>
> |> Assuming:
>
> |> #include <string>
> |> std::string get_string();
> |> int func(const char *p);
>
> |> are the following valid (correct, well-defined, specified,
> |> advisable, standard, etc. etc.):
>
> |> char c = *get_string().c_str();
>
> Valid.
>
> |> func(get_string().c_str());
>
> Maybe. It depends on what func does with the pointer.

Ooops. For some reason, I misread this code when I posted my initial
follow-up (I figured he meant char const *c = ...; and was going to
pass this to func). Of course, in the code he actually wrote, the
storage for c_str() remains valid until after func() has finished. My
mistake.

--
Raoul Gough.
export LESS='-X'

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

0 new messages