Why such a different compilers behavior?

149 Views Asked by At

The code below provides completely different results with different compilers and environments.

  1. 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).
  2. 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.
  3. 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
0

There are 0 best solutions below