I recently watched Nico Josuttis’s Keynote Meeting C++ 2022, and just finished reading the Barry Revzin’s post about that same topic.
The code in question is this
// increment even elements:
for (int& i : coll | std::views::filter(isEven)) {
++i; // UB: but works
}
My question is (maybe for compiler writers), how far is my imagination going, if I think that the UB mandated by [range.filter.iterator]/1 could make the following code,
#include <iostream>
#include <ranges>
#include <vector>
constexpr auto isEven = [](int i){
return i % 2 == 0;
};
bool bar();
bool foo() {
bool b = bar();
std::vector<int> coll{1,2,3,4,5,6,7};
if (b)
for (int& i : coll | std::views::filter(isEven))
++i; // UB: but works
return b;
}
be compiled down to just return false;
, i.e. to this?
foo():
xor eax, eax
ret
I mean, the compiler does see that there’s at least one element in coll
that satisfies isEven
, which means that if b
is true
and the for
loop therefore runs, ++i
would rund, which would lead to UB. Hence the compiler could happily conclude that bar()
must return false
.
Is such “reasoning” entirely impossible for a compiler?
3