Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<span>: How cromulent is span<int, static_cast<size_t>(-2)>? #5280

Open
StephanTLavavej opened this issue Feb 13, 2025 · 0 comments
Open

<span>: How cromulent is span<int, static_cast<size_t>(-2)>? #5280

StephanTLavavej opened this issue Feb 13, 2025 · 0 comments
Labels
LWG issue needed A wording defect that should be submitted to LWG as a new issue

Comments

@StephanTLavavej
Copy link
Member

Raised by @frederick-vs-ja in #5274 (comment).

span<int, static_cast<size_t>(-2)> is bogus, but how bogus? It clearly violates the size_bytes() precondition if called. It also violates all constructor preconditions. But can we static_assert when this type is instantiated? An LWG issue would be nice.

There's implementation divergence: https://godbolt.org/z/7ha8rK18K

#ifdef _MSC_VER
#include <crtdbg.h>
#endif

#include <cstddef>
#include <iostream>
#include <span>
using namespace std;

int main() {
#ifdef _MSC_VER
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
#endif

    constexpr size_t BogusSize = static_cast<size_t>(-2);

    int arr[3]{};
    span<int, BogusSize> sp(arr, BogusSize);  // lies
    cout << "Constructed span." << endl;
    cout << "sp.size_bytes(): " << sp.size_bytes() << endl;
}
  • With VS 2022 17.10 (long before STL Hardening #5274) debug mode, size_bytes() emits a debug assertion:
    Program stdout
    Constructed span.
    Z:/compilers/msvc/14.40.33807-14.40.33811.0/include\span(435) : Assertion failed: size of span in bytes exceeds std::numeric_limits<size_t>::max()
    
  • In STL Hardening #5274, I am static_asserting (unconditionally, regardless of debug mode) when any constructor is instantiated, but not the whole type.
  • With GCC 14.2 libstdc++ debug mode, the constructor emits a debug assertion:
    Program stderr
    /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/span:165:
    In function:
        constexpr std::span<_Type, _Extent>::span(_It, size_type) [with _It = 
        int*; _Type = int; long unsigned int _Extent = 18446744073709551614; 
        size_type = long unsigned int]
    
    Error: function requires a valid iterator range [first, first + count).
    [...]
    
  • With Clang 19.1.0 libc++, a compiler error is emitted due to the constructor taking an array:
    Compiler stderr
    In file included from <source>:7:
    /opt/compiler-explorer/clang-19.1.0/bin/../include/c++/v1/span:281:79: error: array is too large (18446744073709551614 elements)
      281 |   _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {}
          |                                                                               ^~~~~~~
    <source>:19:26: note: in instantiation of template class 'std::span<int, 18446744073709551614>' requested here
       19 |     span<int, BogusSize> sp(arr, BogusSize);  // lies
          |                          ^
    
@StephanTLavavej StephanTLavavej added the LWG issue needed A wording defect that should be submitted to LWG as a new issue label Feb 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LWG issue needed A wording defect that should be submitted to LWG as a new issue
Projects
None yet
Development

No branches or pull requests

1 participant