-
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
Parallel for_each iterators don't have to be mutable #3056
Parallel for_each iterators don't have to be mutable #3056
Conversation
The overloads of for_each that take an execution policy argument do not require that the iterator arguments always be mutable iterators. Whether or not the iterators need to be mutable depends on what the function object does. for_each is unusual, if not unique, in this regard; for all other algorithms the mutability of the iterators is specified by the algorithm. See http://eel.is/c++draft/alg.foreach#7 , though I admit that the wording is not particularly clear about this. Since the compiler can't realiably figure out whether or not the function object modifies the elements in the sequence, for_each should only check for constant iterators (_REQUIRE_PARALLEL_ITERATOR), not mutable iterators (_REQUIRE_CPP17_MUTABLE_ITERATOR). This bug was introduced by microsoft#2960 . That PR should not have changed for_each.
This is an important fix. My experience with C++ parallel algorithms is that it is very common to use For example:
That test program requires this change to compile. (The output will be garbled and in a sort of random order due to the parallelism, but I was just looking for a very quick test case.) |
Thanks for this fix! (And noticing/fixing it so quickly, before STL changes stop flowing into VS 2022 17.4 Preview 3 - we should be able to prevent the bug from ever shipping to customers.) I remember thinking about this question while reviewing the PR (especially because LWG-475 "May the function object passed to |
Credit for finding the bug goes to Pili Latiesa. They contacted me as the author of P2408 to ask if |
I'm speculatively mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for the fix, and thanks to Pili for finding this.
Mmh, I'll note that this isn't a regression, however, this does fix a bug in implementing P2408R5. Thanks for noticing and the quick fix! |
Thanks again for fixing this, and congratulations on your first microsoft/STL commit! 😸 🎉 🚀 |
The overloads of
for_each
andfor_each_n
that take an execution policy argument do not require that the iterator arguments always be mutable iterators. Whether or not the iterators need to be mutable depends on what the function object does.for_each
andfor_each_n
are unusual, if not unique, in this regard; for all other algorithms the mutability of the iterators is specified by the algorithm. See http://eel.is/c++draft/alg.foreach#7 , though I admit that the wording is not particularly clear about this.Since the compiler can't reliably figure out whether or not the function object modifies the elements in the sequence,
for_each
andfor_each_n
should only check for constant iterators (_REQUIRE_PARALLEL_ITERATOR
), not mutable iterators (_REQUIRE_CPP17_MUTABLE_ITERATOR
).This bug was introduced by #2960 . That PR should not have changed
for_each
orfor_each_n
.