Skip to content

<memory>: !_Get_ptr() in the destructors of inout_ptr_t and out_ptr_t _should_ be correct #4964

@frederick-vs-ja

Description

@frederick-vs-ja

Describe the bug

Currently !_Get_ptr() is used in the destructors of inout_ptr_t and out_ptr_t.

STL/stl/inc/memory

Lines 4409 to 4411 in a26f4ad

if (!_Get_ptr()) {
return;
}

STL/stl/inc/memory

Lines 4328 to 4330 in a26f4ad

if (!_Get_ptr()) {
return;
}

However, it seems that nothing in Cpp17NullablePointer ([nullablepointer.requirements]) requires !p to be semantically equivalent to p != nullptr or even to be well-formed. E.g. a type with a deleted member operator! (the NoExclamation type shown below) can still meet the Cpp17NullablePointer requirements.

#include <memory>

struct NoExclamation {
    using pointer = NoExclamation;

    void* p_{};

    NoExclamation() = default;
    constexpr NoExclamation(decltype(nullptr)) noexcept {}

    friend bool operator==(NoExclamation, NoExclamation) = default;
    friend constexpr bool operator==(NoExclamation lhs, decltype(nullptr)) noexcept
    {
        return lhs.p_ == nullptr;
    }

    constexpr explicit operator bool() const noexcept
    {
        return p_ != nullptr;
    }

    void operator!() const = delete; // HERE!
};

int main()
{
    NoExclamation ne{};
    std::out_ptr(ne);
}

Currently no implementation accepts the example due to the deleted operator!.

Command-line test case

Godbolt link

Expected behavior

Perhaps the program should compile.

STL version

a26f4ad (probably every version after #1998)

Additional context

As libc++ and libstdc++ also expect usable operator!, should there be an LWG issue to make current implementation strategies comforming?

Metadata

Metadata

Assignees

No one assigned

    Labels

    blocked on LWGWaiting for WG21 to tell us what to do

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions