diff --git a/docs/headers.md b/docs/headers.md index 498340f..6cd2f44 100644 --- a/docs/headers.md +++ b/docs/headers.md @@ -412,22 +412,36 @@ The `gsl::span` is based on the standardized version of `std::span` which was ad deprecate `gsl::span` when `std::span` finished standardization, however that plan changed when the runtime bounds checking was removed from `std::span`'s design. -The only difference between `gsl::span` and `std::span` is that `gsl::span` strictly enforces runtime bounds checking. -Any violations of the bounds check results in termination of the program. -Like `gsl::span`, `gsl::span`'s iterators also differ from `std::span`'s iterator in that all access operations are bounds checked. +The key differences between `gsl::span` and `std::span` are: +- `gsl::span` strictly enforces runtime bounds checking for all access operations +- Any violations of the bounds check results in termination of the program +- `gsl::span`'s iterators also perform bounds checking, unlike `std::span`'s iterators #### Which version of span should I use? -##### Use `gsl::span` if +The following table compares the different span implementations to help you choose which one is best for your project: -- you want to guarantee bounds safety in your project. - - All data accessing operations use bounds checking to ensure you are only accessing valid memory. -- your project uses C++14 or C++17. - - `std::span` is not available as it was not introduced into the STL until C++20. +| Feature/Version | `std::span` (C++20/23) | Hardened `std::span` (C++26) | `gsl::span` | +|-----------------|------------------------|------------------------------|-------------| +| **C++ Standard** | Requires C++20 or later | Requires C++26 or backported implementation | Works with C++14 or later | +| **Element Access** | No bounds checking | Bounds checking | Bounds checking | +| **Iterator Safety** | No bounds checking | Implementation-defined, may depend on vendor | Full bounds checking | +| **Error Behavior** | Undefined behavior on invalid access | Implementation-defined, may be configurable | Always calls [`std::terminate()`](https://en.cppreference.com/w/cpp/error/terminate) via [gsl::details::terminate()](https://github.com/microsoft/GSL/blob/main/include/gsl/assert#L111-L118) | +| **Performance** | Fastest (no checking) | Varies by implementation and configuration | May have performance impact from bounds checking | -##### Use `std::span` if +**Recommendations:** -- your project is C++20 and you need the performance offered by `std::span`. +- **C++14 & C++17 projects**: Use `gsl::span` as `std::span` is not available. +- **C++20 & C++23 projects**: + - Use `gsl::span` if safety is your priority. + - Use `std::span` if performance is critical and you're confident in your index calculations. +- **C++26 projects**: + - Use `gsl::span` if you need guaranteed iterator safety across all platforms. + - Use hardened `std::span` if you want standard library compliance and acceptable safety. + +**Implementation notes for hardened `std::span` in C++26:** +- For MSVC: See [Microsoft STL Hardening](https://github.com/microsoft/STL/wiki/STL-Hardening) +- For Clang/LLVM: See [libc++ Hardening](https://libcxx.llvm.org/Hardening.html) #### Types