Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Is this legal?

Reply
Thread Tools

Is this legal?

 
 
Michael Sparks
Guest
Posts: n/a
 
      04-17-2004
In this code, the temporary inside_t instantiated in main() goes out of
scope by the time we hit the next line.
MSVC 2003 doesn't complain about that even at the highest warning level. Is
it legal? If so, why?

struct inside_t
{
};

struct outside_t
{
const inside_t& _inside;
outside_t(const inside_t& inside) : _inside(inside)
{
}
};

int main()
{
const outside_t& outside=outside_t(inside_t());
// now, outside._inside is referencing to nowhere
return 0;
}



 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      04-17-2004
"Michael Sparks" <(E-Mail Removed)> wrote...
> In this code, the temporary inside_t instantiated in main() goes out of
> scope by the time we hit the next line.
> MSVC 2003 doesn't complain about that even at the highest warning level.

Is
> it legal? If so, why?
>
> struct inside_t
> {
> };
>
> struct outside_t
> {
> const inside_t& _inside;
> outside_t(const inside_t& inside) : _inside(inside)
> {
> }
> };
>
> int main()
> {
> const outside_t& outside=outside_t(inside_t());
> // now, outside._inside is referencing to nowhere
> return 0;
> }


Is this an interview or a homework question? Read about the lifetime of
a temporary if there is a constant reference bound to it.

Victor


 
Reply With Quote
 
 
 
 
Claudio Jolowicz
Guest
Posts: n/a
 
      04-17-2004
On Sat, 17 Apr 2004, Michael Sparks wrote:

>In this code, the temporary inside_t instantiated in main() goes out of
>scope by the time we hit the next line.
>MSVC 2003 doesn't complain about that even at the highest warning level. Is
>it legal? If so, why?
>
>struct inside_t
>{
>};
>
>struct outside_t
>{
> const inside_t& _inside;
> outside_t(const inside_t& inside) : _inside(inside)
> {
> }
>};
>
>int main()
>{
> const outside_t& outside=outside_t(inside_t());
> // now, outside._inside is referencing to nowhere
> return 0;
>}
>


A temporary object is not destroyed if it is used to initialize a
reference. Example:

int main()
{
const int& r = int();
std::cout << r << std::endl; //r still references the temporary object
return 0;
}

--
Claudio Jolowicz




 
Reply With Quote
 
Michael Sparks
Guest
Posts: n/a
 
      04-17-2004
"Claudio Jolowicz" <(E-Mail Removed)> wrote in message
news(E-Mail Removed). ac.uk...
> A temporary object is not destroyed if it is used to initialize a
> reference. Example:


Yes, I understand that. The question is about a more specific issue.

In main(), the temporary is not used to initialize a reference. It is
simply passed as an argument to a constructor.
It is in the constructor where it is bound to the const reference, and at
that point, it isn't known to be a temporary - it is just a parameter.

Suppose I had broken the code into two compilation units:

--------------------- first compilation unit ---------------------

struct inside_t
{
};

struct outside_t
{
const inside_t& _inside;
outside_t(const inside_t& inside);
};

outside_t:utside_t(const inside_t& inside) : _inside(inside)
{
}

--------------------- end first compilation unit ---------------------

--------------------- second compilation unit ---------------------

struct inside_t
{
};

struct outside_t
{
const inside_t& _inside;
outside_t(const inside_t& inside);
};

int main()
{
const outside_t& outside=outside_t(inside_t());
// now, outside._inside is referencing to nowhere
return 0;
}

--------------------- end second compilation unit ---------------------

Now, it is clear to see that when compiling main(), the compiler could not
have any clue that the temporary inside_t is used to initialize a const
reference. Therefore, it will destroy it after that line.

Also, I have verified this behavior experimentally with MSVC. I more or
less assumed that the behavior was correct, and that MSVC compiled it
correctly - the "is this legal" question was more rhetorical than anything.

What I'm really interested in is *why* this is legal.

Mike


 
Reply With Quote
 
Michael Sparks
Guest
Posts: n/a
 
      04-17-2004
"Victor Bazarov" <(E-Mail Removed)> wrote in message
news:L1igc.160225$K91.412208@attbi_s02...
> Is this an interview or a homework question? Read about the lifetime of
> a temporary if there is a constant reference bound to it.


No, this is not a homework or interview question.
Please see my reply to Claudio Jolowicz.

Also, unless I'm mistaken it has little to do with the lifetime of a
temporary if there is a const reference bound to it.
If that is incorrect, please enlighten me.

Mike


 
Reply With Quote
 
SaltPeter
Guest
Posts: n/a
 
      04-17-2004

"Michael Sparks" <(E-Mail Removed)> wrote in message
news:YLhgc.8654$(E-Mail Removed) m...
> In this code, the temporary inside_t instantiated in main() goes out of
> scope by the time we hit the next line.
> MSVC 2003 doesn't complain about that even at the highest warning level.

Is
> it legal? If so, why?
>


Its your responsability to guarentee an object's scope and lifetime, not the
compiler's. In this case, the outside_t structure invokes a temporary
inside_t object by *default* since outside_t's constructor *requires* a
reference to some inside_t object.

The compiler needs not satisfy the existance of the inside_t object after
the outside_t's cstor was invoked.

<snip>
____________________
Lets define an inside_t object, pass it by reference in order to construct
your outside_t object (which then initializes the inside_ member with a
reference that actually refers to something real). Note that the inside_t
object is never "part-of" the outside_t object, yet its now destroyed last.

#include <iostream>

struct inside_t
{
inside_t() { std::cout << "inside_t cstor\n"; }
~inside_t() { std::cout << "inside_t d~stor\n"; }
};

struct outside_t
{
outside_t(const inside_t& r_inside) : inside_(r_inside)
{
std::cout << "outside_t cstor\n";
}
~outside_t() { std::cout << "outside_t d~stor\n"; }

const inside_t& inside_;
};

int main()
{
inside_t in; // cstor invoked
outside_t out(in); // cstor invoked, in passed by reference
// display member inside_
std::cout << "&out.inside_ = " << &out.inside_ << std::endl;

const outside_t& ref_out = out;
std::cout << "reference ref_out = " << &ref_out << std::endl;
std::cout << "in's address is " << &in << std::endl;

return 0;
}
_________
Think of it this way: write a letter, put it in an envelope with some
address specified and stick an appropriate postage stamp on it. Mail it.
Nobody is going to build a home/apartment at destination in order to
guarentee the delivery of that one piece of mail. A reference works exactly
in the same way.




 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-17-2004
"Michael Sparks" <(E-Mail Removed)> wrote...
> "Victor Bazarov" <(E-Mail Removed)> wrote in message
> news:L1igc.160225$K91.412208@attbi_s02...
> > Is this an interview or a homework question? Read about the lifetime of
> > a temporary if there is a constant reference bound to it.

>
> No, this is not a homework or interview question.
> Please see my reply to Claudio Jolowicz.
>
> Also, unless I'm mistaken it has little to do with the lifetime of a
> temporary if there is a const reference bound to it.
> If that is incorrect, please enlighten me.


If there are two const references in the program, and both are bound
to the two temporaries in the program, then the lifetime of those two
temporaries has _everything_ to do with it. I don't know how to
enlighten you. Just take a look at the code.

Victor


 
Reply With Quote
 
Jorge Rivera
Guest
Posts: n/a
 
      04-18-2004

>
> int main()
> {
> const int& r = int();
> std::cout << r << std::endl; //r still references the temporary object
> return 0;
> }
>


Try that code with you own class, and see if what you're saying holds
true... (No destructor called)

JLR
 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      04-18-2004
Michael Sparks wrote:

> "Claudio Jolowicz" <(E-Mail Removed)> wrote in message
> news(E-Mail Removed). ac.uk...
>> A temporary object is not destroyed if it is used to initialize a
>> reference. Example:

>
> Yes, I understand that. The question is about a more specific issue.
>
> In main(), the temporary is not used to initialize a reference. It is
> simply passed as an argument to a constructor.


Which gets a reference as parameter, which is initialized with the
temporary.

 
Reply With Quote
 
Jakob Bieling
Guest
Posts: n/a
 
      04-18-2004
"Michael Sparks" <(E-Mail Removed)> wrote in message
news:B3jgc.8695$(E-Mail Removed) m...

> In main(), the temporary is not used to initialize a reference.


It is!

> It is
> simply passed as an argument to a constructor.


And that argument is of type 'inside_t const&,' meaning you bind the
temporary to a constant reference.

> It is in the constructor where it is bound to the const reference, and at
> that point, it isn't known to be a temporary - it is just a parameter.


It is known as a reference to a constant 'inside_t.' Meaning, you are
using a 'inside_t const&' to initialize another 'inside_t const&'.

hth
--
jb

(replace y with x if you want to reply by e-mail)


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments