Thread: Performance issues

  1. #16
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    by the way: would that forward-method also work if the remote classes are used as template arguments
    Yes.

  2. #17
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, not always. It would work for templates that don't need a fully defined argument at the point of instantiation.
    auto_ptr is a particularly tricky case. The class template itself doesn't need the type to be fully defined. HOWEVER, the destructor of auto_ptr deletes the object it points to, and delete is evil: it doesn't require the full definition, but if it's not available, it is undefined behaviour as far as the standard is concerned. (In other words, your program is invalid, but you might not notice it immediately - or ever.)
    The trick here is: whether the UB occurs depends on whether the type is fully defined where delete is used. But where is it used? Well, it's used in the auto_ptr destructor, so it's used whereever that is defined. Because auto_ptr is a template, the destructor of any given instantiation is "defined" (instantiated, actually) directly after the first function it is used in. That, in your case, is the destructor of your class. And the destructor of your class might be auto-generated and therefore be auto-defined directly after the class definition (conceptually). Since the definition is not yet available there, it's UB.

    To sum up: assuming you have four files: a pair of .hpp and .cpp for the two classes a and b. Note that a contains an auto_ptr to a b. b doesn't reference a in any form, but the full definition wasn't included in order to keep the inclusion dependencies down. Assume that include guards and appropriate system includes are in place.

    a.hpp
    Code:
    class b;
    
    class a
    {
      std::auto_ptr<b> ptr;
    };
    b.hpp
    Code:
    class b
    {
    };
    a.cpp and b.cpp are irrelevant.

    The above gives undefined behaviour when the a is destructed. Weird, huh? To correct it, you could do this:
    a.hpp
    Code:
    class b;
    
    class a
    {
      std::auto_ptr<b> ptr;
    public:
      ~a();
    };
    a.cpp
    Code:
    #include "a.hpp"
    #include "b.hpp"
    
    a::~a()
    {
    }
    Now the behaviour is well-defined.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #18
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    that sounds really weird to me. Thanks for that nice explanation!

  4. #19
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It is weird. For this reason, Boost.Shared_Ptr was written in such a way that the UB code above would fail to compile.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Performance and footprint of virtual function
    By George2 in forum C++ Programming
    Replies: 8
    Last Post: 01-31-2008, 07:34 PM
  2. File map performance
    By George2 in forum C++ Programming
    Replies: 8
    Last Post: 01-04-2008, 04:18 AM
  3. Observer Pattern and Performance questions
    By Scarvenger in forum C++ Programming
    Replies: 2
    Last Post: 09-21-2007, 11:12 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. inheritance and performance
    By kuhnmi in forum C++ Programming
    Replies: 5
    Last Post: 08-04-2004, 12:46 PM