C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Opt-In Compile Time Bounds Checking

From: Julien Jorge <julien.jorge_at_[hidden]>
Date: Wed, 27 Sep 2023 09:23:45 +0200
On 10/09/2023 07:14, Levo DeLellis via Std-Proposals wrote:
> Attached is a proposal for safespan and nspan which requires certain
> things to be known at compile time.
>
Hello, I gave a quick look at your proposal and I have a couple of
questions :)

Regarding safespan, if I understood correctly there cannot be an access
without prior test confirming that the index is within the bounds. I
wonder how it can be assured for non-trivial indices. Especially, it
seems to prevent any sort of pre-validation of the indices like in the
code below:

     void foo(std::safespan<int> values, std::safespan<std::size_t> order)
     {
       bool valid = true;

       for (std::size_t i : order)
         if (i >= values.size())
           return;

       // All indices are known to be within the bounds here.
       for (std::size_t i : order)
         bar(values[i])
     }

It may be obvious for the programmer that the indices are valid in the
second loop (at least ignoring potential side effects of `bar` on
`order`) but it is non-trivial for the compiler. This specification in
point 2.B in your proposal makes me wondering if this type would
actually be useful for not very specific, maybe trivial, code. Do you
have more complex examples to share? My goal here is to understand the
scope of the feature and see the alternatives when we cannot meet this
scope.

Regarding nspan you wrote:

> Because it is useful to have implicit conversions it should be
ambiguous to use function overloading when the nspan parameter is the
only difference.

I am not sure if you are suggesting a standard-backed special case for
handling function overload declarations or if you are talking about
ambiguity on the call site. With regard to your specification, namely
the point "May be implicitly converted to a nspan of same or smaller
size but never larger", I think the latter works out of the box:

     void foo(std::nspan<int, 24>);
     void foo(std::nspan<int, 42>);

     std::nspan<int, 128> s = …;
     foo(s); // Ambiguous: s is implicitly convertible to
             // both std::nspan<int, 24> and std::nspan<int, 42>

Best regards,
Julien

Received on 2023-09-27 07:23:49