Lifetime of temporaries?

Discussion in 'C++' started by Jorgen Grahn, Mar 24, 2009.

  1. Jorgen Grahn

    Jorgen Grahn Guest

    I should know this, but ...

    Is this code safe?

    std::string foo();
    std::printf("%s", foo().c_str());

    Or is my temporary std::string destroyed before printf()
    is done with it?

    Background:

    I'm sitting with a whole bunch of classes and (for now) only a
    printf-like interface for printing logs/debug info. I was thinking
    about

    - implementing ostream << foo as usual,

    - have a 'template<T> std:string to_string(const T&)' based on it

    - log using the slightly ugly syntax
    log("error in %s: %s",
    to_string(foo).c_str(),
    to_string(bar).c_str());

    It's ugly and extremely wasteful, but I want to define the output
    format in *one* place for each class -- not in every place where I might
    want to print it.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
    \X/ snipabacken.se> R'lyeh wgah'nagl fhtagn!
    Jorgen Grahn, Mar 24, 2009
    #1
    1. Advertising

  2. Jorgen Grahn wrote:
    > I should know this, but ...
    >
    > Is this code safe?


    You need to define "safe". I am not certain it's a standard term.

    > std::string foo();


    OK, 'foo' is a function returing a string.

    > std::printf("%s", foo().c_str());


    This is an expression statement, a function call to 'std::printf' with
    two arguments. The temporary returned by 'foo' lives until the end of
    the full expression (here: the semicolon). The pointer 'c_str' returns
    *also* lives as long as the [temporary] object that has produced it.

    > Or is my temporary std::string destroyed before printf()
    > is done with it?


    'printf' doesn't actually do anything with your temporary. It needs the
    pointer your temporary returns. And actually the pointer can live less
    than the temporary...

    >
    > Background:
    >
    > I'm sitting with a whole bunch of classes and (for now) only a
    > printf-like interface for printing logs/debug info. I was thinking
    > about
    >
    > - implementing ostream << foo as usual,
    >
    > - have a 'template<T> std:string to_string(const T&)' based on it
    >
    > - log using the slightly ugly syntax
    > log("error in %s: %s",
    > to_string(foo).c_str(),
    > to_string(bar).c_str());
    >
    > It's ugly and extremely wasteful, but I want to define the output
    > format in *one* place for each class -- not in every place where I might
    > want to print it.


    Seems like you're on your way to a satisfactory solution.

    Good luck!

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Mar 24, 2009
    #2
    1. Advertising

  3. Jorgen Grahn

    Balog Pal Guest

    "Jorgen Grahn" <>
    >I should know this, but ...
    >
    > Is this code safe?
    >
    > std::string foo();
    > std::printf("%s", foo().c_str());


    > Or is my temporary std::string destroyed before printf()
    > is done with it?


    Temporaries are destroyed at end of the *full-expression*, that mean at the
    ; after the printf call. This use is okay, the problematis would be to call
    some other function taking the const char * and save a copy of it for later
    use.

    > - have a 'template<T> std:string to_string(const T&)' based on it
    >
    > - log using the slightly ugly syntax
    > log("error in %s: %s",
    > to_string(foo).c_str(),
    > to_string(bar).c_str());
    >
    > It's ugly and extremely wasteful, but I want to define the output
    > format in *one* place for each class -- not in every place where I might
    > want to print it.


    You could use some stream-like object especially if you want only strings in
    the format, not all the other format elements. Then have stuff like
    log("error in %s: %s") <<foo << bar << flush;
    or having global object
    log << format("error in %s: %s") << foo << bar; // without flush last line
    waits the next format()

    moving the to_string() code to operator <<;
    Balog Pal, Mar 24, 2009
    #3
  4. Jorgen Grahn

    Jorgen Grahn Guest

    On Tue, 24 Mar 2009 15:44:02 +0100, Balog Pal <> wrote:
    > "Jorgen Grahn" <>
    >>I should know this, but ...
    >>
    >> Is this code safe?


    [It was. Thanks; that was what I suspected.]

    >> - have a 'template<T> std:string to_string(const T&)' based on it
    >>
    >> - log using the slightly ugly syntax
    >> log("error in %s: %s",
    >> to_string(foo).c_str(),
    >> to_string(bar).c_str());
    >>
    >> It's ugly and extremely wasteful, but I want to define the output
    >> format in *one* place for each class -- not in every place where I might
    >> want to print it.

    >
    > You could use some stream-like object especially if you want only strings in
    > the format, not all the other format elements. Then have stuff like
    > log("error in %s: %s") <<foo << bar << flush;
    > or having global object
    > log << format("error in %s: %s") << foo << bar; // without flush last line
    > waits the next format()


    Yes, I have been thinking about something like that, but most code
    using the logging calls is C-like, so the benefit across the whole
    code base would be fairly small => not a high priority.

    > moving the to_string() code to operator <<;


    Actually there was no to_string() code to speak of -- like I mentioned
    above it's a template which uses operator<< to fill a string stream,
    and then return the resulting std::string. I have worked with code which
    used T::toString() methods exclusively, and I never want to deal with
    that again. operator<< is bad enough ;-)

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
    \X/ snipabacken.se> R'lyeh wgah'nagl fhtagn!
    Jorgen Grahn, Mar 26, 2009
    #4
    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. John Miles
    Replies:
    1
    Views:
    310
    tom_usenet
    Jul 30, 2003
  2. kaede
    Replies:
    1
    Views:
    339
    Kevin Goodsell
    Oct 2, 2003
  3. kaede
    Replies:
    3
    Views:
    324
    kaede
    Oct 4, 2003
  4. John Harrison

    lifetime of temporaries

    John Harrison, Apr 23, 2004, in forum: C++
    Replies:
    13
    Views:
    538
    Jerald Fijerald
    Apr 25, 2004
  5. Replies:
    1
    Views:
    281
Loading...

Share This Page