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
495 stars 40 forks source link

integral constant overflow when building unit tests with MSVC #59

Closed vlovich closed 3 years ago

vlovich commented 3 years ago
span-lite\include\nonstd\span.hpp(1302): warning C4307: '*': integral constant overflow
span-lite\test\span.t.cpp(1127): note: see reference to function template instantiation 'nonstd::span_lite::span<const std::byte,18446744073709551615>
 nonstd::span_lite::as_bytes<int,18446744073709551615>(nonstd::span_lite::span<int,18446744073709551615>)' being compiled
span-lite\include\nonstd\span.hpp(1314): warning C4307: '*': integral constant overflow
span-lite\test\span.t.cpp(1148): note: see reference to function template instantiation 'nonstd::span_lite::span<byte,18446744073709551615> nonstd::span_lite::as_writable_bytes<int,18446744073709551615>(nonstd::span_lite::span<int,18446744073709551615>)' being compiled

This appears to just be MSVC being a bit dumb & unable to figure out you never actually multiply with overflow. One solution is to just move the byte extent computation into a helper template struct:

template <typename T, extent_t Extent> struct BytesExtent {
  static constexpr auto value = span_sizeof(T) * Extent;
};

template <typename T> struct BytesExtent<T, dynamic_extent> {
  static constexpr auto value = dynamic_extent;
};

template <typename T, extent_t Extent>
static constexpr auto BytesExtent_v = BytesExtent<T, Extent>::value;

Then you just use BytesExtent_v<T, Extent> everywhere instead of the runtime conditional.

martinmoene commented 3 years ago

Thanks @vlovich, first completing holidays :)