The code below provides completely different results with different compilers and environments.
- With the Visual Studio 2022 (recent version, x64 compiler v19.37) it compiles just fine and outputs the results with some lines of numbers (don’t focus on them, the question is not about the algorithm or output; the key is that the output is provided).
- With godbolt.org | x64 msvc v19.latest and the
/std:c++latest
option explicitly set it compiles, but provides very long assembler dump (really, huge) and no output at all. - With godbolt.org | x86-64c clang 17.0.1 and the ‘-std=c++23’ option explicitly set it doesn’t compile with long list of error messages.
What kind of error makes this code causing so different compilers behavior?
#include <execution>
#include <vector>
#include <iostream>
#include <ranges>
auto comp = [](auto&& a, auto&& b) {
return std::tie(std::get<0>(a), std::get<1>(a)) <
std::tie(std::get<0>(b), std::get<1>(b)); };
auto proj = [](auto&& v) { return v; };
int main()
{
std::vector values = { 7,3,9,2,4,7 };
std::vector indexes = { 0,1,2,3,4,5 };
auto rng = std::ranges::views::zip(indexes, values);
std::ranges::sort(rng, comp, proj);
for (auto i : indexes) {
for (int vi = 0; vi <= i; ++vi) {
std::cout << values[vi] << " ";
}
std::cout << std::endl;
}
}
BTW, they say that ranges were invented particularly to make error messages simpler and more specific. If somebody can explain how you trace these clang error messages here to figure out the problem root cause, I would be thankful, since I am totally lost in this "spaghetti".
Error Messages
In file included from <source>:4:
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4558:14: error: type constraint differs in template redeclaration
4558 | template<copy_constructible _Fp, input_range... _Ws>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4458:14: note: in instantiation of template class 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::_Iterator<true>' requested here
4458 | { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:23: note: in instantiation of member function 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::begin' requested here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:6: note: in instantiation of requirement here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:977:32: note: while substituting template arguments into constraint expression here
977 | concept __member_begin = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
978 | {
| ~
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
980 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: while checking the satisfaction of concept '__member_begin<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
112 | requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
| ^~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:501:21: note: while substituting template arguments into constraint expression here
501 | concept range = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
502 | {
| ~
503 | ranges::begin(__t);
| ~~~~~~~~~~~~~~~~~~~
504 | ranges::end(__t);
| ~~~~~~~~~~~~~~~~~
505 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while checking the satisfaction of concept 'range<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
1059 | template<range _Range>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while substituting template arguments into constraint expression here
1059 | template<range _Range>
| ^~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_algo.h:1793:17: note: while checking constraint satisfaction for template 'borrowed_iterator_t<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' required here
1793 | constexpr borrowed_iterator_t<_Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:22: note: while substituting deduced template arguments into function template 'operator()' [with _Range = zip_view<all_t<vector<int, allocator<int>> &>, all_t<vector<int, allocator<int>> &>> &, _Comp = (lambda at <source>:6:13), _Proj = (lambda at <source>:10:13)]
19 | std::ranges::sort(rng, comp, proj);
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4829:12: note: previous template declaration is here
4829 | template<copy_constructible _Fp, input_range... _Vs>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4558:14: error: type constraint differs in template redeclaration
4558 | template<copy_constructible _Fp, input_range... _Ws>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4458:30: note: in instantiation of template class 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::_Iterator<false>' requested here
4458 | { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:23: note: in instantiation of member function 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::begin' requested here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:6: note: in instantiation of requirement here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:977:32: note: while substituting template arguments into constraint expression here
977 | concept __member_begin = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
978 | {
| ~
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
980 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: while checking the satisfaction of concept '__member_begin<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
112 | requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
| ^~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:501:21: note: while substituting template arguments into constraint expression here
501 | concept range = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
502 | {
| ~
503 | ranges::begin(__t);
| ~~~~~~~~~~~~~~~~~~~
504 | ranges::end(__t);
| ~~~~~~~~~~~~~~~~~
505 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while checking the satisfaction of concept 'range<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
1059 | template<range _Range>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while substituting template arguments into constraint expression here
1059 | template<range _Range>
| ^~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_algo.h:1793:17: note: while checking constraint satisfaction for template 'borrowed_iterator_t<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' required here
1793 | constexpr borrowed_iterator_t<_Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:22: note: while substituting deduced template arguments into function template 'operator()' [with _Range = zip_view<all_t<vector<int, allocator<int>> &>, all_t<vector<int, allocator<int>> &>> &, _Comp = (lambda at <source>:6:13), _Proj = (lambda at <source>:10:13)]
19 | std::ranges::sort(rng, comp, proj);
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4829:12: note: previous template declaration is here
4829 | template<copy_constructible _Fp, input_range... _Vs>
| ^
2 errors generated.
ASM generation compiler returned: 1
In file included from <source>:4:
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4558:14: error: type constraint differs in template redeclaration
4558 | template<copy_constructible _Fp, input_range... _Ws>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4458:14: note: in instantiation of template class 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::_Iterator<true>' requested here
4458 | { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:23: note: in instantiation of member function 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::begin' requested here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:6: note: in instantiation of requirement here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:977:32: note: while substituting template arguments into constraint expression here
977 | concept __member_begin = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
978 | {
| ~
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
980 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: while checking the satisfaction of concept '__member_begin<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
112 | requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
| ^~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:501:21: note: while substituting template arguments into constraint expression here
501 | concept range = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
502 | {
| ~
503 | ranges::begin(__t);
| ~~~~~~~~~~~~~~~~~~~
504 | ranges::end(__t);
| ~~~~~~~~~~~~~~~~~
505 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while checking the satisfaction of concept 'range<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
1059 | template<range _Range>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while substituting template arguments into constraint expression here
1059 | template<range _Range>
| ^~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_algo.h:1793:17: note: while checking constraint satisfaction for template 'borrowed_iterator_t<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' required here
1793 | constexpr borrowed_iterator_t<_Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:22: note: while substituting deduced template arguments into function template 'operator()' [with _Range = zip_view<all_t<vector<int, allocator<int>> &>, all_t<vector<int, allocator<int>> &>> &, _Comp = (lambda at <source>:6:13), _Proj = (lambda at <source>:10:13)]
19 | std::ranges::sort(rng, comp, proj);
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4829:12: note: previous template declaration is here
4829 | template<copy_constructible _Fp, input_range... _Vs>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4558:14: error: type constraint differs in template redeclaration
4558 | template<copy_constructible _Fp, input_range... _Ws>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4458:30: note: in instantiation of template class 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::_Iterator<false>' requested here
4458 | { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:23: note: in instantiation of member function 'std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>>::begin' requested here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:979:6: note: in instantiation of requirement here
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/iterator_concepts.h:977:32: note: while substituting template arguments into constraint expression here
977 | concept __member_begin = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
978 | {
| ~
979 | { __decay_copy(__t.begin()) } -> input_or_output_iterator;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
980 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: while checking the satisfaction of concept '__member_begin<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
112 | requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
| ^~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:112:50: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:501:21: note: while substituting template arguments into constraint expression here
501 | concept range = requires(_Tp& __t)
| ^~~~~~~~~~~~~~~~~~
502 | {
| ~
503 | ranges::begin(__t);
| ~~~~~~~~~~~~~~~~~~~
504 | ranges::end(__t);
| ~~~~~~~~~~~~~~~~~
505 | };
| ~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while checking the satisfaction of concept 'range<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' requested here
1059 | template<range _Range>
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_base.h:1059:12: note: while substituting template arguments into constraint expression here
1059 | template<range _Range>
| ^~~~~
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/bits/ranges_algo.h:1793:17: note: while checking constraint satisfaction for template 'borrowed_iterator_t<std::ranges::zip_view<std::ranges::ref_view<std::vector<int>>, std::ranges::ref_view<std::vector<int>>> &>' required here
1793 | constexpr borrowed_iterator_t<_Range>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:22: note: while substituting deduced template arguments into function template 'operator()' [with _Range = zip_view<all_t<vector<int, allocator<int>> &>, all_t<vector<int, allocator<int>> &>> &, _Comp = (lambda at <source>:6:13), _Proj = (lambda at <source>:10:13)]
19 | std::ranges::sort(rng, comp, proj);
| ^
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/../../../../include/c++/13.2.0/ranges:4829:12: note: previous template declaration is here
4829 | template<copy_constructible _Fp, input_range... _Vs>
| ^
2 errors generated.
Execution build compiler returned: 1