https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118647
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |DUPLICATE
Status|UNCONFIRMED |RESOLVED
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Alfredo Correa from comment #0)
> 1) With std::copy the optimization only happens sometimes. That is, the
> library is demanding that some iterator operators (op* and op==) be
> no-except for actually doing the optimization. That might or might not be a
> bug, but it certainly disagrees with libc++.
It's not a bug, it's very explicitly done that way on purpose:
#if __cpp_lib_concepts
// N.B. this is not the same as nothrow-forward-iterator, which doesn't
// require noexcept operations, it just says it's undefined if they throw.
// Here we require them to be actually noexcept.
template<typename _Iter>
concept __nothrow_contiguous_iterator
= contiguous_iterator<_Iter> && requires (_Iter __i) {
// If this operation can throw then the iterator could cause
// the algorithm to exit early via an exception, in which case
// we can't use memcpy.
{ *__i } noexcept;
};
template<typename _OutIter, typename _InIter, typename _Sent = _InIter>
concept __memcpyable_iterators
= __nothrow_contiguous_iterator<_OutIter>
&& __nothrow_contiguous_iterator<_InIter>
&& sized_sentinel_for<_Sent, _InIter>
&& requires (_OutIter __o, _InIter __i, _Sent __s) {
requires !!__memcpyable<decltype(std::to_address(__o)),
decltype(std::to_address(__i))>::__value;
{ __i != __s } noexcept;
};
#endif
My reading of the standard is that it is not permitted to use std::to_address
to convert arbitrary contiguous iterators to pointers, because the iterators
could use exceptions to alter control flow. I intend to fix that:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3349r0.html
Until that is approved by the committee, libstdc++ is correct and libc++ is
wrong.
I expect it to be approved by the committee next month, then I'll change the
code above.
> 2) With std::ranges::copy the optimization never happens, which definitely
> is a missed opportunity.
Yes, we're aware that ranges::copy is not on a par with std::copy here. See Bug
111053
*** This bug has been marked as a duplicate of bug 111053 ***