martinmoene / span-lite

span lite - A C++20-like span for C++98, C++11 and later in a single-file header-only library
Boost Software License 1.0
494 stars 40 forks source link

Does not build with clang++-6.0 #17

Closed nolange closed 6 years ago

nolange commented 6 years ago

Hello, the tests won't build with clang-6.0, problem is the C++17 configuration in combination with a C++ Library that provides std::byte. First the issue:

[ 33%] Building CXX object test/CMakeFiles/span-main-cpp17.t.dir/span.t.cpp.o
In file included from /home/lano/git/span-lite/test/span.t.cpp:11:
In file included from /home/lano/git/span-lite/test/span-main.t.hpp:14:
/home/lano/git/span-lite/test/lest_cpp03.hpp:648:53: error: call to function
      'operator<<' that is neither visible in the template definition nor found
      by argument-dependent lookup
        std::ostringstream os; os << std::boolalpha << value;
                                                    ^
/home/lano/git/span-lite/test/lest_cpp03.hpp:674:29: note: in instantiation of
      member function 'lest::string_maker<std::byte>::to_string' requested here
    return string_maker<T>::to_string( value );
                            ^
/home/lano/git/span-lite/test/lest_cpp03.hpp:715:34: note: in instantiation of
      function template specialization 'lest::to_string<std::byte>' requested
      here
    std::ostringstream os; os << to_string( lhs ) << " " << op << " " <...
                                 ^
/home/lano/git/span-lite/test/lest_cpp03.hpp:727:92: note: in instantiation of
      function template specialization 'lest::to_string<std::byte, std::byte>'
      requested here
  ...operator==( R const & rhs ) { return result( lhs == rhs, to_string( lhs...
                                                              ^
/home/lano/git/span-lite/test/span.t.cpp:992:19: note: in instantiation of
      function template specialization 'lest::expression_lhs<const std::byte
      &>::operator==<std::byte>' requested here
    EXPECT( vb[0] == b[0] );
                  ^
/home/lano/git/span-lite/test/lest_cpp03.hpp:229:28: note: expanded from macro
      'EXPECT'
# define EXPECT            lest_EXPECT
                           ^
/home/lano/git/span-lite/test/span-main.t.hpp:40:23: note: 'operator<<' should
      be declared prior to the call site
inline std::ostream & operator<<( std::ostream & os, std::byte b )

I used these flags for configuring, clang is version 6.0, libstdc++ is version 7.3.0. cmake -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_COMPILER=clang++-6.0 -DCMAKE_C_COMPILER=clang-6.0..

Same issue persists if I tell clang to use libc++, which might be a useful additional configuration for the automated tests? I generally tend to use IPO for testing as this might cause additional warnings or errors, roughly thats what I had to do:

apt-get install clang++-6.0 libc++abi-dev libc++-dev
cmake -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_COMPILER=clang++-6.0 -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_FLAGS=-stdlib=libc++ ..
nolange commented 6 years ago

Ok, since you allow failures for clang, I suppose that's not news for you ;)

martinmoene commented 6 years ago

Understanding it is a different matter.

nolange commented 6 years ago

Not sure I know what you are asking.

short: enabling IPO detects stuff like ODR violations across source-files, and if your software tests fine with IPO enabled then it will test fine without - the other way around is not guaranteed.

martinmoene commented 6 years ago

Thanks for your explanation. It was a note that I don't understand the source of the compilation error (yet) and a link (for myself) to read up on CMake's policy CMP0069 and IPO. (I could have written something less confusing indeed.)

nolange commented 6 years ago

you need to declare inline std::ostream & operator<<( std::ostream & os, std::byte b ) (test/span-main.t.hpp:40:23)

before accessing it in template< typename T > struct string_maker::to_string (test/lest_cpp03.hpp:648:53)

right now its defined afterwards, you need to at least declare a prototype before using it within template< typename T > struct