C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Temporaries, references, lifetimes and const_cast

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Paul Thomas
Guest





PostPosted: Fri Jun 02, 2006 1:54 am    Post subject: Temporaries, references, lifetimes and const_cast Reply with quote



I know this subject comes up a lot - and I've got the gist of it - but
there is one particular case that I can't work through. Is it legal or not?

This has come up before:

<code>
std::string Func() { return "monkey"; }

int main()
{
const std::string &cstr = Func();

std::string &str = const_cast<std::string &>(cstr);

str = "ape";
}
</code>

and the Jury seems to be out still.
But I want to do something even nastier:

<code>
#include <string>
#include <iostream>

std::string Func() { return "monkey"; }

std::string& Funky(std::string& str){
return str += " magic";
}

std::string& Munky(const std::string& cstr){
return const_cast<std::string &>(cstr);
}

int main(){
//Funky(Func()); <-- no-no!
std::cout << Funky(Munky(Func())) << std::endl;
}

</code>

I haven't had trouble compiling it, but why hasn't the constant
reference bound to the return from Func() gone out of scope when Munky()
returns?

pt.

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





PostPosted: Sat Jun 03, 2006 3:53 am    Post subject: Re: Temporaries, references, lifetimes and const_cast Reply with quote



Paul Thomas wrote:
Quote:
I know this subject comes up a lot - and I've got the gist of it - but
there is one particular case that I can't work through. Is it legal
or not?

This has come up before:

code
std::string Func() { return "monkey"; }

int main()
{
const std::string &cstr = Func();

std::string &str = const_cast<std::string &>(cstr);

str = "ape";
}
/code

and the Jury seems to be out still.

Really? What for? It's allowed. Period.

Quote:
But I want to do something even nastier:

code
#include <string
#include <iostream

std::string Func() { return "monkey"; }

std::string& Funky(std::string& str){
return str += " magic";
}

std::string& Munky(const std::string& cstr){
return const_cast<std::string &>(cstr);
}

int main(){
//Funky(Func()); <-- no-no!
std::cout << Funky(Munky(Func())) << std::endl;
}

/code

I haven't had trouble compiling it, but why hasn't the constant
reference bound to the return from Func() gone out of scope when
Munky() returns?

It's an argument to 'Munky'. It lives until the full expression
that contains the function call is evaluated.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Tomás
Guest





PostPosted: Sat Jun 03, 2006 7:13 pm    Post subject: Re: Temporaries, references, lifetimes and const_cast Reply with quote



Victor Bazarov posted:


Quote:
code
std::string Func() { return "monkey"; }

int main()
{
const std::string &cstr = Func();

std::string &str = const_cast<std::string &>(cstr);

str = "ape";
}
/code

and the Jury seems to be out still.

Really? What for? It's allowed. Period.


That's not the general consensus. Here's a quote from Tom Widmer in a
post to comp.std.c++ in the thread "Constness of return by value
temporaries":

"It may or may not be fine. The problem is that the code is permitted to
copy the return of Func() into a temporary of type "const
vector<string>" before binding it to cvec (see 8.5.3/5), and it is
unspecified whether it will do so or not, so basically the code is not
necessarily absent of undefined behaviour."

Here's a link to the thread:

http://groups.google.ie/group/comp.std.c++/browse_frm/thread/c8dd97ce2bb9
4e0b/6edac02c40c8e64e?lnk=st&q=temporary+const+group%3Acomp.std.c%2B%
2B+author%3ATom%C3%A1s&rnum=1&hl=en#6edac02c40c8e64e


-Tomás

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





PostPosted: Sun Jun 04, 2006 6:09 pm    Post subject: Re: Temporaries, references, lifetimes and const_cast Reply with quote

johnchx2 (AT) yahoo (DOT) com wrote:
Quote:
Victor Bazarov wrote:
Paul Thomas wrote:
This has come up before:

code
std::string Func() { return "monkey"; }

int main()
{
const std::string &cstr = Func();

std::string &str = const_cast<std::string &>(cstr);

str = "ape";
}
/code

and the Jury seems to be out still.
Really? What for? It's allowed. Period.

There's a corner case that could make this undefined. 8.5.3/5
allows the creation of a temporary of type const std::string
in the initialization of cstr. Since the temporary object is
const, modifying it through a non-const reference gives rise
to undefined behavior.

That's an interesting point. It pretty much does mean that the
above code is undefined behavior.

The case involving a non class type is even more interesting,
e.g.:
int const& i = 3 ;
const_cast< int& >( i ) = 4 ;
In this case, a "temporary of type "cv1 T1" [const int] is
created [...]". Except that temporaries are rvalues, and
non-class type rvalues don't have cv-qualifiers.

Finally, of course, note the subtle difference in :

char const* foo() { return "monkey" ; }

// ...
std::string const& s = foo() ;
const_cast< std::string& >( s ) = "ape" ;

In this case, there clearly is undefined behavior, because the
temporary of type "cv1 T1" (i.e. const std::string) must be
created. (Since the types aren't reference compatible, we fall
into the last point in §8.5.3/5.)

Quote:
Since the standard is about to revoke the permission to create
a copy in this situation, I'd be surprised if the code above
didn't already work on the vast majority of implementations,
so the point is of limited practical importance.

More than simply revoking the permission to create a copy, I
think this part is being reworked somewhat -- and off hand, I
don't know what the decision will be on the legality of any of
the above.

I might add that today, some compilers, for example, g++, DO
make a copy, in specific cases. Arguably, even, it is required
in some specific cases, for lifetime of temporary issues. Which
means that the current situation is that it is not clearly
defined whether it is undefined or not.

--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.