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 ***