Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 376421
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T14:35:50+00:00 2026-05-12T14:35:50+00:00

My question (which will follow after this, sorry about the long intro, the question

  • 0

My question (which will follow after this, sorry about the long intro, the question is down there in bold) is originally inspired by Item 23 in Herb Sutters Exceptional C++ where we find something like this:

<snip>


...
int main()
{
  GenericTableAlgorithm a( "Customer", MyWorker() );
  a.Process();
}

with


class GenericTableAlgorithm
{
public:
  GenericTableAlgorithm( const string& table,
                         GTAClient&    worker );
  bool Process(); 
private:
  struct GenericTableAlgorithmImpl* pimpl_; //implementation
};
class GTAClient
{
   ///...
   virtual bool ProcessRow( const PrimaryKey& ) =0;
   //...
};
class MyWorker : public GTAClient 
{
  // ... override Filter() and ProcessRow() to
  //     implement a specific operation ...
};


</snip>

Now, I have the following problems with that code (and no, I in no way doubt Mr. Sutter’s prowess as a C++ expert):

    1. The example like that will not work, since GTAClient& worker is a non-const reference which can’t take a temporary, but well, it might have been written pre-standard or a typo, whatever, that’s not my point.
    2. What makes me wonder is what he is going to do with the worker reference, even if Problem 1. is ignored.

      Obviously the intention is to have MyWorker used in the NVI of GenericTableAlgorithm accessed by GTAClient (polymorphic) interface; this rules out that the implementation owns a (value)member of type GTAClient, since that would cause slicing etc. value-semantics don’t mix well with polymorphism.

      It cannot have a data member of type MyWorker either since that class is unknown to GenericTableAlgorithm.

      So I conclude it must have been meant to be used via pointer or reference, preserving the original object and polymorphic nature.
    3. Since pointers to temporary objects (MyWorker()) are rarely a good idea, i assume the author’s plan was to use the extended life-time of temporaries bound to (const) references, and store such a reference in the object pimpl_ points to and use it from there. (Note: there is also no clone-member function in GTAClient, which could have made this work; let’s not assume there is a RTTI-typeinfo-based Factory lurking in the background.)

      And here (finally!) my question sets in:(How) can passing a temporary to to a class’ reference member with extended life-time be done legally ?


    The standard in §12.2.5(the C++0x version but it’s the same in C++, don’t know about the chapter number) makes the following exception from lifetime extension:
    “-A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.”

    Therefore the object cannot be used in the call of the client code a.Process(); because the referenced temporary from MyWorker() is already dead!

    Consider now an example of my own crafting that demonstrates the problem (tested on GCC4.2):

    #include <iostream>
    using std::cout; 
    using std::endl;
    
    struct oogie {
     ~oogie()
     {
      cout << "~oogie():" << this << ":" << m_i << endl;
     }
     oogie(int i_)
      : m_i(i_)
     {
      cout << "oogie():" << this << ":" << m_i << endl;
     }
    
     void call() const
     {
      cout << "call(): " << this << ":" << m_i << endl;
     }
     int m_i;
    };
    
    oogie func(int i_=100)
    {
     return oogie(i_);
    }
    
    struct kangoo 
    {
     kangoo(const oogie& o_)
     : m_o(o_)
     {
     }
    
     const oogie& m_o;
    };
    
    int main(int c_, char ** v_)
    {
    
     //works as intended
     const oogie& ref = func(400);
     //kablewy machine
     kangoo s(func(1000));
    
     cout << ref.m_i << endl;
    
     //kangoo's referenced oogie is already gone
     cout << s.m_o.m_i << endl;
    
     //OK, ref still alive
     ref.call();
     //call on invalid object
     s.m_o.call();
    
     return 0;
    }
    

    which produces the output

    oogie():0x7fff5fbff780:400
    oogie():0x7fff5fbff770:1000
    ~oogie():0x7fff5fbff770:1000
    400
    1000
    call(): 0x7fff5fbff780:400
    call(): 0x7fff5fbff770:1000
    ~oogie():0x7fff5fbff780:400
    

    You can see that in the case of const oogie& ref the immediately bound-to-reference temporary return value of func() has the extended lifetime of said reference (until end of main), so it’s OK.


    BUT: The 1000-oogie object is already destroyed right after kangoo-s was constructed. The code works, but we are dealing with an undead object here…

    So to pose the question again:

    Firstly, Am I missing something here and the code is correct/legal?.

    Secondly, why does GCC give me no warning of this, even with -Wall specified? Should it? Could it?

    Thanks for your time,

    martin

    • 1 1 Answer
    • 1 View
    • 0 Followers
    • 0
    Share
    • Facebook
    • Report

    Leave an answer
    Cancel reply

    You must login to add an answer.

    Forgot Password?

    Need An Account, Sign Up Here

    1 Answer

    • Voted
    • Oldest
    • Recent
    • Random
    1. Editorial Team
      Editorial Team
      2026-05-12T14:35:50+00:00Added an answer on May 12, 2026 at 2:35 pm

      I think this is a tricky part that is not too clear. There was a similar question just a couple of days ago.

      By default temporaries are destroyed in reverse order of construction when the full-expression in which they were created completes. Up to here everything is fine and understood, but then exceptions arise (12.2 [class.temporary]/4,5) and things become confusing.

      Instead of dealing with the exact wording and definitions in the standard I will approach the problem from an engineering / compiler perspective. Temporaries are created in the stack, when a function completes the stack frame is freed (the stack pointer is moved back to the original position before the function call started).

      This implies that a temporary can never survive the function in which it was created. More exactly, it cannot survive the scope where it was defined, even if it can in fact survive the full-expression in which it was created.

      None of the exceptions in the standard falls out of this restriction, in all cases the lifetime of the temporary is extended to a point that is guaranteed not to exceed the function call in which the temporary was created.

      • 0
      • Reply
      • Share
        Share
        • Share on Facebook
        • Share on Twitter
        • Share on LinkedIn
        • Share on WhatsApp
        • Report

    Sidebar

    Related Questions

    This may be a painfully simply question for which I will be mocked but
    I know about this question: Which (third-party) debug visualizers for Visual Studio 2005/2008 do
    This question originally asked which is the best method for uploading files via SFTP
    This question is related to another question which I asked yesterday! List all links
    This isn't a holy war, this isn't a question of which is better. What
    I just want to clarify one thing. This is not a question on which
    I asked a question earlier about which language to use for an AI prototype.
    I have a question concerning this code which I want to run on QNX:
    Please refer to this background question. After constructing this COUNT, how would I then
    I am using an open source .Net library which uses MSMQ underneath. After about

    Explore

    • Home
    • Add group
    • Groups page
    • Communities
    • Questions
      • New Questions
      • Trending Questions
      • Must read Questions
      • Hot Questions
    • Polls
    • Tags
    • Badges
    • Users
    • Help
    • SEARCH

    Footer

    © 2021 The Archive Base. All Rights Reserved
    With Love by The Archive Base

    Insert/edit link

    Enter the destination URL

    Or link to existing content

      No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.