
You can see practical manifestations of these examples in e.g https://github.com/pdimov/hash2/blob/develop/include/boost/hash2/md5.hpp where at https://github.com/pdimov/hash2/blob/26b16023dc639ae354e246458719e4b569bc1d9... you have BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] ) with the implicit precondition that `block` points at at least 64 valid bytes, and then at https://github.com/pdimov/hash2/blob/26b16023dc639ae354e246458719e4b569bc1d9... you have for( int i = 0; i < 16; ++i ) { x[ i ] = detail::read32le( block + i * 4 ); } which relies on this implicit precondition to read 16 subspans of size 4. (detail::read32le also has an implicit precondition that its argument points at at least 4 valid bytes.) Replacing these pointer arguments with fixed size spans would theoretically result in all the bounds checks (except one at the top level) being optimized out even if the functions aren't inlined.
-----Original Message----- From: Peter Dimov
Sent: Friday, 6 December 2024 19:13 To: boost@lists.boost.org Subject: RE: [boost] [hash2][review] Early review (due to holidays) Andrey Semashev wrote:
And fixed extents are not as useful as the dynamic extent in general, in my experience, as most of the time we deal with variable-sized sequences.
I also used to think that way, but that was because I didn't understand the purpose of span.
The purpose of span is to replace pointer arguments. If your function takes
void f1( unsigned char p[] );
you use
void f1( span<unsigned char> p );
and if it takes
void f2( unsigned char p[4] );
you use
void f2( span
p ); The fixed extent span here does two things: first, it inserts a runtime check that the extent of the passed span is >= 4.
void g( span<unsigned char> p ) { f2( p ); // implicit assert( p.size() >= 4 ); }
Second, it can be used to optimize out runtime checks in operator[]:
void f2( span
p ) { uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); } Since it's statically known that 0<4, 1<4, 2<4, 3<4, these accesses don't cause any asserts to be inserted.