Skip to content

<ranges>: Questionable conditional noexcept #1269

@CaseyCarter

Description

@CaseyCarter

The range adaptors defined in <ranges> strengthen noexcept more aggressively than much of the STL. Upon noticing that a couple of conditional noexcepts in transform_view were incorrect for non-zero IDL modes, I threw together some preprocessor stuffs to "turn off" a conditional noexcept in non-zero IDL:

STL/stl/inc/ranges

Lines 1016 to 1020 in be0441c

#if _ITERATOR_DEBUG_LEVEL == 0
#define _NOEXCEPT_IDL0(...) noexcept(__VA_ARGS__)
#else
#define _NOEXCEPT_IDL0(...)
#endif // _ITERATOR_DEBUG_LEVEL == 0

So that precondition-checking machinery that calls user-provided functions:

STL/stl/inc/ranges

Lines 1064 to 1067 in be0441c

constexpr void _Check_dereference() const {
_STL_VERIFY(_Parent != nullptr, "cannot dereference value-initialized transform_view iterator");
_STL_VERIFY(_Current != _RANGES end(_Parent->_Range), "cannot dereference end transform_view iterator");
}

is usable from functions that want to provide conditional noexcept:

STL/stl/inc/ranges

Lines 1112 to 1120 in be0441c

_NODISCARD constexpr decltype(auto) operator*() const
_NOEXCEPT_IDL0(noexcept(_STD invoke(*_Parent->_Fun, *_Current))) /* strengthened */ {
#if _ITERATOR_DEBUG_LEVEL != 0
_Check_dereference();
_STL_VERIFY(
_Parent->_Fun, "Cannot dereference iterator into transform_view with no transformation function");
#endif // _ITERATOR_DEBUG_LEVEL != 0
return _STD invoke(*_Parent->_Fun, *_Current);
}

This is a bit of a hack, and it was received as such. I've since observed that other range adaptors have the same problem and simply slam into noexcept:

STL/stl/inc/ranges

Lines 876 to 882 in be0441c

_NODISCARD friend constexpr range_rvalue_reference_t<_Vw> iter_move(const _Iterator& _It) noexcept(
noexcept(_RANGES iter_move(_It._Current))) {
#if _ITERATOR_DEBUG_LEVEL != 0
_It._Check_dereference();
#endif // _ITERATOR_DEBUG_LEVEL != 0
return _RANGES iter_move(_It._Current);
}

(Note that conditional noexcept on iter_move and iter_swap overloads is not strengthened, but Standard-mandated.)

We need to devise policy for how we want to handle conditional noexcept on functions that call user-provided in "debug" modes only, including both strengthened and non-strengthened cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedSomething works now, yay!questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions