`<span>`: How cromulent is `span<int, static_cast<size_t>(-2)>`?
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Raised by @frederick-vs-ja in https://github.com/microsoft/STL/pull/5274#discussion_r1951827253.
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 #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 #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 | ^
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the std::span constructors and size_bytes() behavior described in the issue, then review PR #5274 and its discussion. Reproduce the sample across MSVC, libstdc++, and libc++ using the linked Compiler Explorer case. Done means the intended handling of the invalid extent is decided and the implementation behavior is made consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100