returning a string from an ostringstream

Discussion in 'C++' started by Thomas Lenz, Oct 22, 2007.

  1. Thomas Lenz

    Thomas Lenz Guest

    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
     
    Thomas Lenz, Oct 22, 2007
    #1
    1. Advertising

  2. 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
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 22, 2007
    #2
    1. Advertising

  3. Thomas Lenz

    Jim Langston Guest

    "Thomas Lenz" <> wrote in message
    news:471ce6c4$0$16664$-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.
     
    Jim Langston, Oct 23, 2007
    #3
  4. Thomas Lenz

    Thomas Lenz Guest

    am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

    > "Thomas Lenz" <> wrote in message
    > news:471ce6c4$0$16664$-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
     
    Thomas Lenz, Oct 23, 2007
    #4
  5. On 2007-10-23 13:30, Thomas Lenz wrote:
    > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:
    >
    >> "Thomas Lenz" <> wrote in message
    >> news:471ce6c4$0$16664$-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
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 23, 2007
    #5
  6. Thomas Lenz

    Jim Langston Guest

    "Thomas Lenz" <> wrote in message
    news:471ddb50$0$13112$-online.net...
    > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:
    >
    >> "Thomas Lenz" <> wrote in message
    >> news:471ce6c4$0$16664$-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
     
    Jim Langston, Oct 23, 2007
    #6
  7. Thomas Lenz

    Rajesh S R Guest

    On Oct 23, 7:00 pm, "Jim Langston" <> wrote:
    > "Thomas Lenz" <> wrote in message
    >
    > news:471ddb50$0$13112$-online.net...
    >
    >
    >
    > > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

    >
    > >> "Thomas Lenz" <> wrote in message
    > >>news:471ce6c4$0$16664$-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.
     
    Rajesh S R, Oct 23, 2007
    #7
  8. Thomas Lenz

    Jim Langston Guest

    "Rajesh S R" <> wrote in message
    news:...
    > On Oct 23, 7:00 pm, "Jim Langston" <> wrote:
    >> "Thomas Lenz" <> wrote in message
    >>
    >> news:471ddb50$0$13112$-online.net...
    >>
    >>
    >>
    >> > am Dienstag 23 Oktober 2007 11:05 schrieb Jim Langston:

    >>
    >> >> "Thomas Lenz" <> wrote in message
    >> >>news:471ce6c4$0$16664$-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.
     
    Jim Langston, Oct 23, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Victor Bazarov
    Replies:
    0
    Views:
    849
    Victor Bazarov
    Jun 25, 2003
  2. Bala2508
    Replies:
    28
    Views:
    1,175
    Jim Langston
    Nov 3, 2007
  3. Replies:
    2
    Views:
    408
    James Kanze
    Jan 17, 2008
  4. Fab
    Replies:
    4
    Views:
    1,418
    Thomas J. Gritzan
    Mar 24, 2008
  5. Replies:
    12
    Views:
    985
    Jerry Coffin
    Jun 2, 2008
Loading...

Share This Page