932. unique_ptr(pointer p) for pointer deleter types

Section: 20.3.1.3.2 [unique.ptr.single.ctor] Status: Resolved Submitter: Howard Hinnant Opened: 2008-11-26 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [unique.ptr.single.ctor].

View all issues with Resolved status.

Discussion:

Addresses US 79

20.3.1.3.2 [unique.ptr.single.ctor]/5 no longer requires for D not to be a pointer type. I believe this restriction was accidently removed when we relaxed the completeness reuqirements on T. The restriction needs to be put back in. Otherwise we have a run time failure that could have been caught at compile time:

{
unique_ptr<int, void(*)(void*)> p1(malloc(sizeof(int)));  // should not compile
}  // p1.~unique_ptr() dereferences a null function pointer
unique_ptr<int, void(*)(void*)> p2(malloc(sizeof(int)), free);  // ok

[ Post Summit: ]

Recommend Tentatively Ready.

[ 2009-07 Frankfurt ]

Moved from Tentatively Ready to Open only because the wording needs to be improved for enable_if type constraining, possibly following Robert's formula.

[ 2009-07 Frankfurt: ]

We need to consider whether some requirements in the Requires paragraphs of [unique.ptr] should instead be Remarks.

Leave Open. Howard to provide wording, and possibly demonstrate how this can be implemented using enable_if.

[ 2009-07-27 Howard adds: ]

The two constructors to which this issue applies are not easily constrained with enable_if as they are not templated:

unique_ptr();
explicit unique_ptr(pointer p);

To "SFINAE" these constructors away would take heroic effort such as specializing the entire unique_ptr class template on pointer deleter types. There is insufficient motivation for such heroics. Here is the expected and reasonable implementation for these constructors:

unique_ptr()
    : ptr_(pointer())
    {
        static_assert(!is_pointer<deleter_type>::value,
            "unique_ptr constructed with null function pointer deleter");
    }
explicit unique_ptr(pointer p)
    : ptr_(p)
    {
        static_assert(!is_pointer<deleter_type>::value,
            "unique_ptr constructed with null function pointer deleter");
    }

I.e. just use static_assert to verify that the constructor is not instantiated with a function pointer for a deleter. The compiler will automatically take care of issuing a diagnostic if the deleter is a reference type (uninitialized reference error).

In keeping with our discussions in Frankfurt, I'm moving this requirement on the implementation from the Requires paragraph to a Remarks paragraph.

[ 2009-08-17 Daniel adds: ]

It is insufficient to require a diagnostic. This doesn't imply an ill-formed program as of 3.17 [defns.diagnostic] (a typical alternative would be a compiler warning), but exactly that seems to be the intend. I suggest to use the following remark instead:

Remarks: The program shall be ill-formed if this constructor is instantiated when D is a pointer type or reference type.

Via the general standard rules of 4.1 [intro.compliance] the "diagnostic required" is implied.

[ 2009-10 Santa Cruz: ]

Moved to Ready.

[ 2010-03-14 Howard adds: ]

We moved N3073 to the formal motions page in Pittsburgh which should obsolete this issue. I've moved this issue to NAD Editorial, solved by N3073.

Rationale:

Solved by N3073.

Proposed resolution:

Change the description of the default constructor in 20.3.1.3.2 [unique.ptr.single.ctor]:

unique_ptr();

-1- Requires: D shall be default constructible, and that construction shall not throw an exception. D shall not be a reference type or pointer type (diagnostic required).

...

Remarks: The program shall be ill-formed if this constructor is instantiated when D is a pointer type or reference type.

Add after 20.3.1.3.2 [unique.ptr.single.ctor]/8:

unique_ptr(pointer p);

...

Remarks: The program shall be ill-formed if this constructor is instantiated when D is a pointer type or reference type.