 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Paul Thomas Guest
|
Posted: Fri Jun 02, 2006 1:54 am Post subject: Temporaries, references, lifetimes and const_cast |
|
|
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
|
Posted: Sat Jun 03, 2006 3:53 am Post subject: Re: Temporaries, references, lifetimes and const_cast |
|
|
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
|
Posted: Sat Jun 03, 2006 7:13 pm Post subject: Re: Temporaries, references, lifetimes and const_cast |
|
|
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
|
Posted: Sun Jun 04, 2006 6:09 pm Post subject: Re: Temporaries, references, lifetimes and const_cast |
|
|
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 |
|
 |
|
|
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
|
|