Scope of temporary variables

G

gerald.dalley

I've been trying to pin down the scoping rules for temporary variables
in C++. I know that doing something like:

string s("abc");
const char *t = (s+"def").c_str();
cout << t;

is invalid since (s+"def") creates a temporary which goes out of scope,
thus leaving t a dangling pointer. What I'm wondering is whether
temporaries go out of scope when their expression terminates or when
their statement terminates. For example, is the following wrong?

string s("abc");
cout << (s+"def").c_str();
 
K

Kai-Uwe Bux

I've been trying to pin down the scoping rules for temporary variables
in C++. I know that doing something like:

string s("abc");
const char *t = (s+"def").c_str();
cout << t;

is invalid since (s+"def") creates a temporary which goes out of scope,
thus leaving t a dangling pointer. What I'm wondering is whether
temporaries go out of scope when their expression terminates or when
their statement terminates.

If I recall correctly, the scope is the largest expression of which the
temporary is a subexpression. (And then there was something about function
calls).
For example, is the following wrong?

string s("abc");
cout << (s+"def").c_str();

That would be fine since 'cout << (s+"def").c_str()' is an expression.


Best

Kai-Uwe Bux
 
G

gerald.dalley

Kai-Uwe Bux said:
If I recall correctly, the scope is the largest expression of which the
temporary is a subexpression. (And then there was something about function
calls).


That would be fine since 'cout << (s+"def").c_str()' is an expression.


Best

Kai-Uwe Bux

Good point. I guess I should really ask it in function-call form:
string s("abc");
printf("%s\n", (s+"def").c_str());
 
K

Kai-Uwe Bux

Good point. I guess I should really ask it in function-call form:
string s("abc");
printf("%s\n", (s+"def").c_str());

I think, 'printf("%s\n", (s+"def").c_str())' is an expression, too. It
happens to be of type void. Generally, in C++, a function call is just a
special form of expression. The statement is, again, an expression
statement and the function is just called in the course of evaluating the
expression (which, somewhat strangely, can be of type void!).

In other words, you should be fine here, too.


Best

Kai-Uwe Bux
 
V

Victor Bazarov

Kai-Uwe Bux said:
[..]
I think, 'printf("%s\n", (s+"def").c_str())' is an expression, too. It
happens to be of type void. [..]

Close. It's of type 'int'. 'printf' "returns the number of characters
transmitted or a negative value if an output or encoding error occurred".

V
 
S

shaanxxx

I've been trying to pin down the scoping rules for temporary variables
in C++. I know that doing something like:

string s("abc");
const char *t = (s+"def").c_str();
cout << t;

is invalid since (s+"def") creates a temporary which goes out of scope,
thus leaving t a dangling pointer. What I'm wondering is whether
temporaries go out of scope when their expression terminates or when
their statement terminates. For example, is the following wrong?

string s("abc");
cout << (s+"def").c_str();

scope would be the block in which is defined.
 
S

shaanxxx

I've been trying to pin down the scoping rules for temporary variables
in C++. I know that doing something like:

string s("abc");
const char *t = (s+"def").c_str();
cout << t;

is invalid since (s+"def") creates a temporary which goes out of scope,
thus leaving t a dangling pointer. What I'm wondering is whether
temporaries go out of scope when their expression terminates or when
their statement terminates. For example, is the following wrong?

string s("abc");
cout << (s+"def").c_str();

scope of temporaries would be the block in which temporaries are
defined.
 
G

gerald.dalley

shaanxxx said:
scope of temporaries would be the block in which temporaries are
defined.

I'm pretty sure the scoping of temporaries is tighter than block level.
The following code:

class dstring : public string
{
public:
dstring(const char *s) : string(s), i(n++) {};
dstring(string const &s) : string(s), i(n++) {};
virtual ~dstring() { cout << "dstring " << i << " destructing\n";
}
dstring operator+(const char *s) { return dstring((string)*this +
s); }
private:
int i;
static int n;
};
int dstring::n = 0;

void dstringTests()
{
const char *t = (dstring("abc") + "def").c_str();
printf("t = '%s'\n\n", t);

printf("inlined = '%s'\n", (dstring("abc") + "def").c_str());
printf("\n");

printf("inlined#2 = '%s'\n", (dstring("abc") + "def").c_str());
printf("\n");
}

outputs:

dstring 1 destructing
dstring 0 destructing
t = ''

inlined = 'abcdef'
dstring 3 destructing
dstring 2 destructing

inlined#2 = 'abcdef'
dstring 5 destructing
dstring 4 destructing

If the scoping of temporaries was block-level, none of the "dstring x
destructing" lines would be printed until after the "x = y" lines.
These results are for VS2005, g++ 3.3.5, and g++ 3.4.4, with and
without optimizations.
 
D

dasjotre

shaanxxx said:
scope of temporaries would be the block in which temporaries are
defined.

Not correct:
"Unless bound to a reference or used to initialize a named
object, a temporary object is destroyed at the end of the
full expression in which it was created." [Stroustrup]

that is in:

const char *t = (s+"def").c_str();

the temp string created from s+"def" is destroyed at ';'
 
G

Gerald Dalley

dasjotre said:
shaanxxx said:
scope of temporaries would be the block in which temporaries are
defined.

Not correct:
"Unless bound to a reference or used to initialize a named
object, a temporary object is destroyed at the end of the
full expression in which it was created." [Stroustrup]

that is in:

const char *t = (s+"def").c_str();

the temp string created from s+"def" is destroyed at ';'

Thanks. That's exactly what I was looking for.
 
F

Frederick Gotham

shaanxxx posted:
scope of temporaries would be the block in which temporaries are
defined.


Please refrain from posting absolute bullshit.

Temporaries are destroyed at the next semi-colon.

This causes a slight problem if you have something like:

x++, Func(x);

If "x" is a built-in type, then this is fine because there's a sequence point
between each side of the comma.

If "x" is a user-defined type, however, then you'll have a problem if you use
the "proxy method" of postincrementing your object, because the temporary
will be destroyed at then end of the statement, rather than before the next
side of the comma.
 
A

Alan Johnson

I've been trying to pin down the scoping rules for temporary variables
in C++. I know that doing something like:

string s("abc");
const char *t = (s+"def").c_str();
cout << t;

is invalid since (s+"def") creates a temporary which goes out of scope,
thus leaving t a dangling pointer. What I'm wondering is whether
temporaries go out of scope when their expression terminates or when
their statement terminates. For example, is the following wrong?

string s("abc");
cout << (s+"def").c_str();

Scope is a property of names, and since a temporary doesn't have a
name, it doesn't have a scope.

What you are asking about is lifetime.

The other responses in this thread do a good job of answering your
question.
 
F

Frederick Gotham

shaanxxx posted:
Thanks for correction. I would appreciate if you can use better word.

Let's make a deal:

(1) I'll use a better word if

(2) You make sure you post correct info.
 
S

shaanxxx

Frederick said:
shaanxxx posted:


Let's make a deal:

(1) I'll use a better word if

(2) You make sure you post correct info.

deal, You are appreciated.
But I have seen people quoting wrong, replies what they get are good
and corrective.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top