C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Why some standard functions having a wide contract are not marked as conditionally noexcept?

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 25 Sep 2022 13:03:48 -0400
On Sun, Sep 25, 2022 at 8:43 AM blacktea hamburger via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Is conditional noexcept only for swap function, move-constructor, or
> move-assignment operator?
> However, according to cppreference
> <https://en.cppreference.com/w/cpp/language/noexcept_spec#Notes>, it is
> useful for any function templates.
>

The noexcept keyword was introduced in order to solve a problem with C++11
std::vector (as compared to C++98 std::vector). That problem (the "vector
pessimization") applies only to the move constructor. (Well, and the
destructor; but C++11 decided to make destructors noexcept by default, and
the C++11 STL decided not to care at all about types whose destructors
*weren't* noexcept.)

It is *traditional* to mark your move-assignment operator and your ADL
`swap` functions also with `noexcept` (and to make it conditional if you're
writing a template where those operations are only sometimes noexcept), but
there is no particular *engineering reason* to do so — nothing in the
standard library actually cares whether those operations are noexcept or
not.

See:
https://stackoverflow.com/questions/66459162/where-do-standard-library-or-compilers-leverage-noexcept-move-semantics-other-t/66498981#66498981
https://quuxplusone.github.io/blog/2022/08/26/vector-pessimization/

The standard library sometimes marks functions as `noexcept` so that they
don't "get in the way of" the user-programmer's attempts to determine the
noexceptness of a complicated expression; e.g.
    struct S { int f() noexcept; };
    std::unique_ptr<S> p;
    static_assert(noexcept(p->f())); // OK
works only because `std::unique_ptr<S>::operator->() const` is marked
`noexcept` in the library. But this is at least 50% ad-hoc; for example,
notice that unique_ptr's `operator*` and `operator->`
<https://en.cppreference.com/w/cpp/memory/unique_ptr/operator*> are marked
(conditionally) noexcept, but its `operator[]
<https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_at>` is not.
    std::unique_ptr<S[]> pa;
    static_assert(!noexcept(pa[0].f())); // except on MSVC
Microsoft's STL applies `noexcept` to unique_ptr::operator[] anyway, as vendors
are permitted to add noexcept wherever they like
<https://eel.is/c++draft/conforming#res.on.exception.handling-5>.

–Arthur

Received on 2022-09-25 17:04:00