-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<algorithm>: Double forwarding in std::ranges::clamp
causes unwanted moving
#3970
Comments
Your comparator doesn't meet the semantic requirements of See also |
I don't get it. |
But the copy may be obtained from move construction, so it is considered able to modify the argument when used in |
I agree that N4950 [concept.regularinvocable]/1 "The We're required to cache the projection (we get only 3 invocations, not 4), so the question is what value category we present to the comparator. The Standard depicts the original value category, so I agree that our approach is correct. That said, this Standardese is admittedly squirelly. |
I hate that. Non-range algorithms allowed functors taking params by value 😞 |
We looked at libc++'s implementation and they are non-conformantly invoking the projection 4 times instead of 3. (N4950 [alg.clamp]/5 is unambiguous.) The possible changes for us are (just listing them without any order of preference):
We could also raise this as an LWG issue due to the implementation divergence and potential for surprising users. After talking about this at the weekly maintainer meeting, we are united in our desire for the LWG to tell us what to do. |
I hope this was the intention, but was underspecified due to an oversight |
Currently libstdc++ chooses option 4 (cache the invocation as |
MSVC STL used to behave like this until #1898. See #1898 (comment). CC @timsong-cpp. |
Any of 3-5 makes the algorithm underconstrained because |
I reported libc++'s standard violation and they're now classifying it as a bug (llvm/llvm-project#64717), so going down that route might end up swapping the behavior with libc++. |
Curiously, they didn't seem to render the algorithm underconstrained before P2609R3... |
It's harder to construct an example but they do exist: https://gcc.godbolt.org/z/3fsdbTx5Y |
I think this should be closed as invalid, see also LLVM-68413. |
We talked about this at the weekly maintainer meeting, and now that libc++ agrees with our behavior, we believe that we have no reason to keep this issue open. Of course, if someone would like to file an LWG issue to further clarify the Standard here then that is entirely welcome (but please don't tell us and libc++ to do something different now 😹). |
Describe the bug
STL/stl/inc/algorithm
Lines 10600 to 10608 in 8674b3d
As the projection function in the following test case returns a non-const copy of the argument that is taken by const reference and the comparator takes its arguments by value,
std::forward
causes_Temp
to be moved instead of copied when calling the comparator, resulting in causing anstd::out_of_range
exception on the second comparator invocation. From my understanding of the C++ standard, both the projection and the comparator are conforming to its requirements, although I am not too sure about it.Both libstdc++ and libc++ don't exhibit this behavior.
Command-line test case
Expected behavior
No
std::out_of_range
exception should be thrown.STL version
Microsoft Visual Studio Community 2022
Version 17.8.0 Preview 1.0
The text was updated successfully, but these errors were encountered: