shared_ptr to incomplete type, undefined behavior?

Discussion in 'C++' started by Alan Johnson, May 13, 2006.

  1. Alan Johnson

    Alan Johnson Guest

    From the standard 5.3.5/5:
    "If the object being deleted has incomplete class type at the point of
    deletion and the complete class has a non-trivial destructor or a
    deallocation function, the behavior is undefined."

    In the program below, what constitutes "point of deletion"? Presumably,
    since delete is called somewhere within shared_ptr's template, the point
    of deletion is the same place at which the template is instantiated.

    Does the following program therefore exhibit undefined behavior, or am I
    missing something? (Does this generalize to all cases in which a
    shared_ptr is created from a forward reference?)


    #include <iostream>
    #include <boost/shared_ptr.hpp>

    // Forward reference.
    class A ;

    // A has incomplete type here.
    boost::shared_ptr<A> pa ;

    class A
    {
    public:
    A() { std::cout << "A()" << std::endl ; }
    ~A() { std::cout << "~A()" << std::endl ; }
    } ;

    int main()
    {
    pa.reset(new A) ;
    }

    --
    Alan Johnson
     
    Alan Johnson, May 13, 2006
    #1
    1. Advertising

  2. * Alan Johnson:
    > From the standard 5.3.5/5:
    > "If the object being deleted has incomplete class type at the point of
    > deletion and the complete class has a non-trivial destructor or a
    > deallocation function, the behavior is undefined."
    >
    > In the program below, what constitutes "point of deletion"? Presumably,
    > since delete is called somewhere within shared_ptr's template, the point
    > of deletion is the same place at which the template is instantiated.
    >
    >
    > Does the following program therefore exhibit undefined behavior, or am I
    > missing something? (Does this generalize to all cases in which a
    > shared_ptr is created from a forward reference?)
    >
    >
    > #include <iostream>
    > #include <boost/shared_ptr.hpp>
    >
    > // Forward reference.
    > class A ;
    >
    > // A has incomplete type here.
    > boost::shared_ptr<A> pa ;
    >
    > class A
    > {
    > public:
    > A() { std::cout << "A()" << std::endl ; }
    > ~A() { std::cout << "~A()" << std::endl ; }
    > } ;
    >
    > int main()
    > {
    > pa.reset(new A) ;
    > }


    If you move the definition of class A to a separate file, plus a factory
    function f that produces a raw pointer, and use f in 'main' instead of
    direct use of 'new', then yes, in that case you would have UB --
    except that the Boost code checks for this, so it won't compile:

    // verify that types are complete for increased safety

    template<class T> inline void checked_delete(T * x)
    {
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
    }

    However, as your code is it compiles, at least with MSVC 7.1, and so
    (what an argument!) I think the instantiation of the template is at the
    point of actual usage in 'main'.

    Note that boost::shared_ptr provides a way to avoid UB even when you do
    have an incomplete type, by passing a deleter function to the
    constructor (that's why boost::shared_ptr is great for the PIMPL idiom).

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, May 13, 2006
    #2
    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. Philippe Guglielmetti
    Replies:
    4
    Views:
    909
    tom_usenet
    Oct 9, 2003
  2. Mantorok Redgormor
    Replies:
    70
    Views:
    1,802
    Dan Pop
    Feb 17, 2004
  3. gk245
    Replies:
    2
    Views:
    1,220
    Christopher Benson-Manica
    May 6, 2006
  4. Colin Caughie
    Replies:
    1
    Views:
    738
    Shooting
    Aug 29, 2006
  5. Replies:
    7
    Views:
    1,123
    Juha Nieminen
    Nov 29, 2007
Loading...

Share This Page