Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2024-12-06 17:30:13


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/26b16023dc639ae354e246458719e4b569bc1d97/include/boost/hash2/md5.hpp#L110

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/26b16023dc639ae354e246458719e4b569bc1d97/include/boost/hash2/md5.hpp#L119-L122

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 <pdimov_at_[hidden]>
> Sent: Friday, 6 December 2024 19:13
> To: boost_at_[hidden]
> 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<unsigned char, 4> 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<unsigned char, 4> 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.
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk