Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > returning a string from an ostringstream

Reply
Thread Tools

returning a string from an ostringstream

 
 
Thomas Lenz
Guest
Posts: n/a
 
      10-22-2007
Please consider the following code snippet:

string myfunction()
{ ostringstream oss;
oss << "junk";
// do something more with oss; I can't make it const...
return oss.str();
}

Is the returned string object still valid after myfunction() has returned? I
wonder because oss should be destroyed at the bottom '}', shouldn't it? So
what about its string? (The above code seems to work on my machine, but is
it guaranteed to work?)

Or is it safer to explicitly construct the string to return as a temporary
object, like

return string(oss.str());

?

Thanks in advance for any comments,

Thomas



 
Reply With Quote
 
 
 
 
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
Posts: n/a
 
      10-22-2007
On 2007-10-22 20:06, Thomas Lenz wrote:
> Please consider the following code snippet:
>
> string myfunction()
> { ostringstream oss;
> oss << "junk";
> // do something more with oss; I can't make it const...
> return oss.str();
> }
>
> Is the returned string object still valid after myfunction() has returned? I
> wonder because oss should be destroyed at the bottom '}', shouldn't it? So
> what about its string? (The above code seems to work on my machine, but is
> it guaranteed to work?)


It is safe because myfunction() returns a string (and not a reference or
pointer to string) so the value returned from oss.str() will be copied
when myfunction() returns.

--
Erik Wikström
 
Reply With Quote
 
 
 
 
Jim Langston
Guest
Posts: n/a
 
      10-23-2007
"Thomas Lenz" <(E-Mail Removed)> wrote in message
news:471ce6c4$0$16664$(E-Mail Removed)-online.net...
> Please consider the following code snippet:
>
> string myfunction()
> { ostringstream oss;
> oss << "junk";
> // do something more with oss; I can't make it const...
> return oss.str();
> }
>
> Is the returned string object still valid after myfunction() has returned?
> I
> wonder because oss should be destroyed at the bottom '}', shouldn't it? So
> what about its string? (The above code seems to work on my machine, but is
> it guaranteed to work?)
>
> Or is it safer to explicitly construct the string to return as a temporary
> object, like
>
> return string(oss.str());
>
> ?


As Victor says, you are returning by copy. You are returning a std::string,
so oss.str() is copied into a temporary, which is returned.

It would be a problem, however, if you returned a reference or a pointer.

std::string& myfunction()
{ ostringstream oss;
oss << "junk";
// do something more with oss; I can't make it const...
return oss.str();
}

Now you would have a problem, because you are returning a reference (a type
of pointer) to something that is destroyed when the function ends.


 
Reply With Quote
 
Thomas Lenz
Guest
Posts: n/a
 
      10-23-2007
am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

> "Thomas Lenz" <(E-Mail Removed)> wrote in message
> news:471ce6c4$0$16664$(E-Mail Removed)-online.net...
>> Please consider the following code snippet:
>>
>> string myfunction()
>> { ostringstream oss;
>> oss << "junk";
>> // do something more with oss; I can't make it const...
>> return oss.str();
>> }
>>
>> Is the returned string object still valid after myfunction() has
>> returned? I
>> wonder because oss should be destroyed at the bottom '}', shouldn't it?
>> So what about its string? (The above code seems to work on my machine,
>> but is it guaranteed to work?)
>>
>> Or is it safer to explicitly construct the string to return as a
>> temporary object, like
>>
>> return string(oss.str());
>>
>> ?

>
> As Victor says, you are returning by copy. You are returning a
> std::string, so oss.str() is copied into a temporary, which is returned.
>
> It would be a problem, however, if you returned a reference or a pointer.
>
> std::string& myfunction()
> { ostringstream oss;
> oss << "junk";
> // do something more with oss; I can't make it const...
> return oss.str();
> }
>
> Now you would have a problem, because you are returning a reference (a
> type of pointer) to something that is destroyed when the function ends.


thanks everybody.

So there are two string objects involved: one being returned by oss.str(),
and will die when myfunction() returns, and a copied one that lives outside
of myfunction(), right?

What happened if I change the return statement to

return string(oss.str());

? Would this yield 3 string objects? (one coming from oss.str(), one
produced by the string(...) Constructor, and one copied by the return
statement)? (Assuming the compiler doesn't optimize it away)

thanks,
Thomas



 
Reply With Quote
 
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
Posts: n/a
 
      10-23-2007
On 2007-10-23 13:30, Thomas Lenz wrote:
> am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:
>
>> "Thomas Lenz" <(E-Mail Removed)> wrote in message
>> news:471ce6c4$0$16664$(E-Mail Removed)-online.net...
>>> Please consider the following code snippet:
>>>
>>> string myfunction()
>>> { ostringstream oss;
>>> oss << "junk";
>>> // do something more with oss; I can't make it const...
>>> return oss.str();
>>> }
>>>
>>> Is the returned string object still valid after myfunction() has
>>> returned? I
>>> wonder because oss should be destroyed at the bottom '}', shouldn't it?
>>> So what about its string? (The above code seems to work on my machine,
>>> but is it guaranteed to work?)
>>>
>>> Or is it safer to explicitly construct the string to return as a
>>> temporary object, like
>>>
>>> return string(oss.str());
>>>
>>> ?

>>
>> As Victor says, you are returning by copy. You are returning a
>> std::string, so oss.str() is copied into a temporary, which is returned.
>>
>> It would be a problem, however, if you returned a reference or a pointer.
>>
>> std::string& myfunction()
>> { ostringstream oss;
>> oss << "junk";
>> // do something more with oss; I can't make it const...
>> return oss.str();
>> }
>>
>> Now you would have a problem, because you are returning a reference (a
>> type of pointer) to something that is destroyed when the function ends.

>
> thanks everybody.
>
> So there are two string objects involved: one being returned by oss.str(),
> and will die when myfunction() returns, and a copied one that lives outside
> of myfunction(), right?
>
> What happened if I change the return statement to
>
> return string(oss.str());
>
> ? Would this yield 3 string objects? (one coming from oss.str(), one
> produced by the string(...) Constructor, and one copied by the return
> statement)? (Assuming the compiler doesn't optimize it away)


Yes.

--
Erik Wikström
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      10-23-2007
"Thomas Lenz" <(E-Mail Removed)> wrote in message
news:471ddb50$0$13112$(E-Mail Removed)-online.net...
> am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:
>
>> "Thomas Lenz" <(E-Mail Removed)> wrote in message
>> news:471ce6c4$0$16664$(E-Mail Removed)-online.net...
>>> Please consider the following code snippet:
>>>
>>> string myfunction()
>>> { ostringstream oss;
>>> oss << "junk";
>>> // do something more with oss; I can't make it const...
>>> return oss.str();
>>> }
>>>
>>> Is the returned string object still valid after myfunction() has
>>> returned? I
>>> wonder because oss should be destroyed at the bottom '}', shouldn't it?
>>> So what about its string? (The above code seems to work on my machine,
>>> but is it guaranteed to work?)
>>>
>>> Or is it safer to explicitly construct the string to return as a
>>> temporary object, like
>>>
>>> return string(oss.str());
>>>
>>> ?

>>
>> As Victor says, you are returning by copy. You are returning a
>> std::string, so oss.str() is copied into a temporary, which is returned.
>>
>> It would be a problem, however, if you returned a reference or a pointer.
>>
>> std::string& myfunction()
>> { ostringstream oss;
>> oss << "junk";
>> // do something more with oss; I can't make it const...
>> return oss.str();
>> }
>>
>> Now you would have a problem, because you are returning a reference (a
>> type of pointer) to something that is destroyed when the function ends.

>
> thanks everybody.
>
> So there are two string objects involved: one being returned by oss.str(),
> and will die when myfunction() returns, and a copied one that lives
> outside
> of myfunction(), right?
>
> What happened if I change the return statement to
>
> return string(oss.str());
>
> ? Would this yield 3 string objects? (one coming from oss.str(), one
> produced by the string(...) Constructor, and one copied by the return
> statement)? (Assuming the compiler doesn't optimize it away)


Yes, but be careful of "lives outside of myfunction". It only lives as long
as the stament. For instance:

std::string Foo = MyFunction(); // Okay
std::string& Foo = MyFunction(); // Not okay

The string that MyFunction returns is a temporary object. It will only live
as long as the statement that the MyFunction() call is on. So if you
actually want to do something with the string, you got to copy it yet again,
or use it right away (such as an output statement).

std::cout << MyFunction(); // Okay


 
Reply With Quote
 
Rajesh S R
Guest
Posts: n/a
 
      10-23-2007
On Oct 23, 7:00 pm, "Jim Langston" <(E-Mail Removed)> wrote:
> "Thomas Lenz" <(E-Mail Removed)> wrote in message
>
> news:471ddb50$0$13112$(E-Mail Removed)-online.net...
>
>
>
> > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

>
> >> "Thomas Lenz" <(E-Mail Removed)> wrote in message
> >>news:471ce6c4$0$16664$(E-Mail Removed) r-online.net...
> >>> Please consider the following code snippet:

>
> >>> string myfunction()
> >>> { ostringstream oss;
> >>> oss << "junk";
> >>> // do something more with oss; I can't make it const...
> >>> return oss.str();
> >>> }

>
> >>> Is the returned string object still valid after myfunction() has
> >>> returned? I
> >>> wonder because oss should be destroyed at the bottom '}', shouldn't it?
> >>> So what about its string? (The above code seems to work on my machine,
> >>> but is it guaranteed to work?)

>
> >>> Or is it safer to explicitly construct the string to return as a
> >>> temporary object, like

>
> >>> return string(oss.str());

>
> >>> ?

>
> >> As Victor says, you are returning by copy. You are returning a
> >> std::string, so oss.str() is copied into a temporary, which is returned.

>
> >> It would be a problem, however, if you returned a reference or a pointer.

>
> >> std::string& myfunction()
> >> { ostringstream oss;
> >> oss << "junk";
> >> // do something more with oss; I can't make it const...
> >> return oss.str();
> >> }

>
> >> Now you would have a problem, because you are returning a reference (a
> >> type of pointer) to something that is destroyed when the function ends.

>
> > thanks everybody.

>
> > So there are two string objects involved: one being returned by oss.str(),
> > and will die when myfunction() returns, and a copied one that lives
> > outside
> > of myfunction(), right?

>
> > What happened if I change the return statement to

>
> > return string(oss.str());

>
> > ? Would this yield 3 string objects? (one coming from oss.str(), one
> > produced by the string(...) Constructor, and one copied by the return
> > statement)? (Assuming the compiler doesn't optimize it away)

>
> Yes, but be careful of "lives outside of myfunction". It only lives as long
> as the stament. For instance:
>
> std::string Foo = MyFunction(); // Okay
> std::string& Foo = MyFunction(); // Not okay
>


Won't this produce a compilation error?
U are initializing a non-const reference by an rvalue.

 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      10-23-2007
"Rajesh S R" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> On Oct 23, 7:00 pm, "Jim Langston" <(E-Mail Removed)> wrote:
>> "Thomas Lenz" <(E-Mail Removed)> wrote in message
>>
>> news:471ddb50$0$13112$(E-Mail Removed)-online.net...
>>
>>
>>
>> > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

>>
>> >> "Thomas Lenz" <(E-Mail Removed)> wrote in message
>> >>news:471ce6c4$0$16664$(E-Mail Removed) r-online.net...
>> >>> Please consider the following code snippet:

>>
>> >>> string myfunction()
>> >>> { ostringstream oss;
>> >>> oss << "junk";
>> >>> // do something more with oss; I can't make it const...
>> >>> return oss.str();
>> >>> }

>>
>> >>> Is the returned string object still valid after myfunction() has
>> >>> returned? I
>> >>> wonder because oss should be destroyed at the bottom '}', shouldn't
>> >>> it?
>> >>> So what about its string? (The above code seems to work on my
>> >>> machine,
>> >>> but is it guaranteed to work?)

>>
>> >>> Or is it safer to explicitly construct the string to return as a
>> >>> temporary object, like

>>
>> >>> return string(oss.str());

>>
>> >>> ?

>>
>> >> As Victor says, you are returning by copy. You are returning a
>> >> std::string, so oss.str() is copied into a temporary, which is
>> >> returned.

>>
>> >> It would be a problem, however, if you returned a reference or a
>> >> pointer.

>>
>> >> std::string& myfunction()
>> >> { ostringstream oss;
>> >> oss << "junk";
>> >> // do something more with oss; I can't make it const...
>> >> return oss.str();
>> >> }

>>
>> >> Now you would have a problem, because you are returning a reference (a
>> >> type of pointer) to something that is destroyed when the function
>> >> ends.

>>
>> > thanks everybody.

>>
>> > So there are two string objects involved: one being returned by
>> > oss.str(),
>> > and will die when myfunction() returns, and a copied one that lives
>> > outside
>> > of myfunction(), right?

>>
>> > What happened if I change the return statement to

>>
>> > return string(oss.str());

>>
>> > ? Would this yield 3 string objects? (one coming from oss.str(), one
>> > produced by the string(...) Constructor, and one copied by the return
>> > statement)? (Assuming the compiler doesn't optimize it away)

>>
>> Yes, but be careful of "lives outside of myfunction". It only lives as
>> long
>> as the stament. For instance:
>>
>> std::string Foo = MyFunction(); // Okay
>> std::string& Foo = MyFunction(); // Not okay
>>

>
> Won't this produce a compilation error?
> U are initializing a non-const reference by an rvalue.


Which?

Attempting to return oss.str(); as a std::string& results in a compile error
(which is one reason it's not okay).
A reference that is not to 'const' cannot be bound to a non-lvalue

Attempting to intilaize a reference to a temporary is also producing a
compile time error. Returning oss.str() as a std::string and
std::string& Foo = MyFunction(); // Not okay
results in
error C2040: 'Foo' : 'std::string &' differs in levels of indirection from
'std::string'
error C2440: 'initializing' : cannot convert from 'std::string' to
'std::string &'

Luckily the compiler is smart enough to keep us from doing most dumb stuff.


 
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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Feeding string into ostringstream only uses up to the first null? coomberjones@gmail.com C++ 12 06-02-2008 03:14 AM
ostringstream output to C-string Fab C++ 4 03-24-2008 07:11 PM
string vs. ostringstream schoedl@gmail.com C++ 2 01-17-2008 09:46 AM
std::string and std::ostringstream performances Bala2508 C++ 28 11-03-2007 03:22 AM
Re: std::ostringstream unexpected behavior with .net 2003. Victor Bazarov C++ 0 06-25-2003 10:20 PM



Advertisments