473,699 Members | 2,087 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

cast to non-const reference of a function's return object

hi,

recently i discovered a memory leak in our code; after some investigation i
could reduce it to the following problem:
return objects of functions are handled as temporary objects, hence their
dtor is called immediately and not at the end of the function. to be able to
use return objects (to avoid copying) i often assign them to a const
reference.
now, casting a const return object from a function to a non-const reference
to this return object calls immediately the dtor of the return object
anyway, any further operation deals with a non-valid object then. if i do
this in two steps - first holding a const reference to the return object and
then const_casting it, everything works like i expected it.

does anybody know whether the compiler behaves correctly?
i use the following short example to illustrate my question:

const string getastring()
{
return string();
}

void funcWmemleak()
{
string& str = const_cast<stri ng&>(getastring ());
str = "test"; // this is already an invalid object because the dtor was
called before (and won't ever be called again of course)
}

void funcWOmemleak()
{
const string& str1 = getastring();
string& str = const_cast<stri ng&>(str1);
str = "test";
}

int main()
{
funcWmemleak();
funcWOmemleak() ;
}

--
klaus triendl
Jul 22 '05 #1
5 3746
On Wed, 02 Jun 2004 08:09:01 GMT, "klaus triendl" <tr********@mbo x.at>
wrote:
hi,

recently i discovered a memory leak in our code;
I think you mean "use of a dangling reference" rather than "memory
leak".

after some investigation icould reduce it to the following problem:
return objects of functions are handled as temporary objects, hence their
dtor is called immediately and not at the end of the function. to be able to
use return objects (to avoid copying) i often assign them to a const
reference.
now, casting a const return object from a function to a non-const reference
to this return object calls immediately the dtor of the return object
anyway, any further operation deals with a non-valid object then. if i do
this in two steps - first holding a const reference to the return object and
then const_casting it, everything works like i expected it.

does anybody know whether the compiler behaves correctly?


Yes, binding a temporary directly to a const reference extends the
lifetime of the temporary to match that of the reference. You can't
bind a temporary to a non-const reference, so there's no way of doing
the lifetime extension using a non-const ref.

Note, since you return a const string, using the returned string as a
non-const string results in undefined behaviour. You can only safely
use an object that has had const cast away as a non-const object if it
wasn't originally declared const.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #2
"tom_usenet " <to********@hot mail.com> wrote in message
news:<a2******* *************** **********@4ax. com>...
On Wed, 02 Jun 2004 08:09:01 GMT, "klaus triendl" <tr********@mbo x.at>
wrote:
hi,

recently i discovered a memory leak in our code;
I think you mean "use of a dangling reference" rather than "memory
leak".

in our code the returned object is a reference counting pointer and the
string "test" is a new object which is not freed causing a memory leak
(reported by the debugger as such).
after some investigation i
could reduce it to the following problem:
return objects of functions are handled as temporary objects, hence their
dtor is called immediately and not at the end of the function. to be able touse return objects (to avoid copying) i often assign them to a const
reference.
now, casting a const return object from a function to a non-const referenceto this return object calls immediately the dtor of the return object
anyway, any further operation deals with a non-valid object then. if i do
this in two steps - first holding a const reference to the return object andthen const_casting it, everything works like i expected it.

does anybody know whether the compiler behaves correctly?
Yes, binding a temporary directly to a const reference extends the
lifetime of the temporary to match that of the reference. You can't
bind a temporary to a non-const reference, so there's no way of doing
the lifetime extension using a non-const ref.

if the temporary is non-const i can bind it to a non-const reference. at
least with vc++7 it is possible.
Note, since you return a const string, using the returned string as a
non-const string results in undefined behaviour. You can only safely
use an object that has had const cast away as a non-const object if it
wasn't originally declared const.

well, that's an argument; and i can easily solve that problem.
but my question still remains whether the const_cast in the function
"funcWmemle ak" is a good reason that the non-const reference is a non-valid
object after the assignment or not.

--
klaus triendl
Jul 22 '05 #3
On Wed, 02 Jun 2004 14:07:20 GMT, "klaus triendl" <tr********@mbo x.at>
wrote:
Yes, binding a temporary directly to a const reference extends the
lifetime of the temporary to match that of the reference. You can't
bind a temporary to a non-const reference, so there's no way of doing
the lifetime extension using a non-const ref.if the temporary is non-const i can bind it to a non-const reference. at
least with vc++7 it is possible.


This is a non-conforming compiler extension. On VC7.1 I get a warning,
and compiling with /Za (ISO mode) I get an error.
Note, since you return a const string, using the returned string as a
non-const string results in undefined behaviour. You can only safely
use an object that has had const cast away as a non-const object if it
wasn't originally declared const.well, that's an argument; and i can easily solve that problem.


Indeed, that paragraph was just an aside.
but my question still remains whether the const_cast in the function
"funcWmemlea k" is a good reason that the non-const reference is a non-valid
object after the assignment or not.


If you perform the const_cast, then you are not directly binding the
reference to the temporary, and the lifetime will not be extended,
hence you have a "dangling reference" that you can't use. It is
synonymous to this conforming code that exhibits the same problem, and
doesn't use any Microsoft extensions:

#include <string>
#include <iostream>
using namespace std;

int main()
{
string const& s = static_cast<str ing const&>(string( "foo"));
cout << s << '\n';
}

Because s isn't bound directly to the temporary (it is bound to the
result of the static cast), it doesn't extend the temporary's lifetime
and the cout call has undefined behaviour since the temporary has
already been destroyed. Remove the static_cast and it's fine. See
12.2/5 in the C++ standard.

Clear?

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #4
"klaus triendl" <tr********@mbo x.at> wrote in message news:<sa******* ***********@new s.chello.at>...
after some investigation i
could reduce it to the following problem:
return objects of functions are handled as temporary objects, hence their
dtor is called immediately and not at the end of the function. to be able touse return objects (to avoid copying) i often assign them to a const
reference.
now, casting a const return object from a function to a non-const referenceto this return object calls immediately the dtor of the return object
anyway, any further operation deals with a non-valid object then. if i do
this in two steps - first holding a const reference to the return object andthen const_casting it, everything works like i expected it.

does anybody know whether the compiler behaves correctly?


Yes, binding a temporary directly to a const reference extends the
lifetime of the temporary to match that of the reference. You can't
bind a temporary to a non-const reference, so there's no way of doing
the lifetime extension using a non-const ref.

if the temporary is non-const i can bind it to a non-const reference. at
least with vc++7 it is possible.
Note, since you return a const string, using the returned string as a
non-const string results in undefined behaviour. You can only safely
use an object that has had const cast away as a non-const object if it
wasn't originally declared const.

well, that's an argument; and i can easily solve that problem.
but my question still remains whether the const_cast in the function
"funcWmemle ak" is a good reason that the non-const reference is a non-valid
object after the assignment or not.


Yes, it is a valid reference until the const reference that the
temporary was originally bound to is destroyed (i.e. goes out of
scope), provided that the destructor for the original object is not
called in the interim (which is highly unlikely given the context).

HTH, Dave Moore
Jul 22 '05 #5
> Because s isn't bound directly to the temporary (it is bound to the
result of the static cast), it doesn't extend the temporary's lifetime
and the cout call has undefined behaviour since the temporary has
already been destroyed. Remove the static_cast and it's fine. See
12.2/5 in the C++ standard.

Clear?


clear as glass :)
thx for the explanation. it's good to know that the compiler considers the
const_cast a function returning a result.

and thx to dave moore for your posting.
klaus
Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
1724
by: Christopher Benson-Manica | last post by:
If you had an unsigned int that needed to be cast to a const myClass*, would you use const myClass* a=reinterpret_cast<const myClass*>(my_val); or const myClass* a=(const myClass*)myVal; ?
36
6681
by: MSG | last post by:
The answer is neither. Use macros. #define ALLOC(size, type) ((type) *) malloc((size) * sizeof(type)) #define NEW(type, name, size) (type) * (name) = ALLOC((size), (type)) They are both type-safe and concise. Compare: NEW(int, x, 1000);
12
1716
by: Martin | last post by:
Two questions relating to FAQ answer 12.42. (1) In the statement s.i16 |= (unsigned)(getc(fp) << 8); i16 is declared int. The reason for casting to (unsigned) is explained as guarding against sign extension. But left-shifting will always fill vacated bits with zero (assuming the right operand is nonnegative and less than the number of bits in the left expression's type). So how is the cast useful?
14
19338
by: google-newsgroups | last post by:
Hello, even (or because?) reading the standard (ISO/IEC 9899/1999) I do not understand some issues with volatile. The background is embedded programming where data is exchanged between main program flow and interrupts. At the organisation I work, instead of declaring a variable volatile, it is casted to volatile when necessary:
1
1890
by: Daniel | last post by:
HI, <asp:TableCell BackColor="#000066" ID="tblcell" Width='<%# DataBinder.Eval(Container.DataItem, "PRODUCT_ID") %>'/> code at the above is displaying the message Specified cast is not valid. How to cast the width's value into integer? i already out of ideas.
16
1537
by: the.duckman | last post by:
G'Day. Anybodey got an idea on this problem. Say I have a function object doCast(object obj, Type t); It's job is to cast the obect (obj) to a new type (t) and return it. Sounds so simple, but I cant seem to find a way to do it without some prety extravigant hacks.
9
2602
by: Joe | last post by:
I need to cast the correct way HMENU mymenu; int stuff; .... stuff=(int)(long)(HMENU)mymenu; ....
4
2537
by: Pavel Minaev | last post by:
There was an earlier discussion regarding which one is faster - a throwing cast - "(Foo)obj", or a non-throwing one - "obj as Foo", when both are available for a given type and value. The consensus was that, since a check has to be made by the compiler in either case, the speed should be equivalent in case object is indeed of a requested type. Sounds perfectly reasonable, but I've spotted the following in the .NET source code (from MS...
15
2380
by: Lloyd Dupont | last post by:
Don't mistake generic type for what you would like them to be!! IFoo<Ahas nothing in common with IFoo<B>! They are completely different type create dynamically at runtime. What you ask is a bit akin to ask: "the System.Web.UI and System.Windows.Controls namespace both contains a Control class, could I use one in place of the other? common they have the same name!" If you want to use a method common to both you should do as Alun...
0
8697
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9184
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8929
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
5878
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4380
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4634
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3061
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2357
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2013
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.