C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Draft 2: Error on out-of-bounds index

From: Oliver Hunt <oliver_at_[hidden]>
Date: Fri, 29 Aug 2025 18:23:20 -0700
> On Aug 29, 2025, at 4:55 PM, Levo D via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On Fri, Aug 29, 2025 at 04:16:36PM -0700, Oliver Hunt wrote:
>>
>>
>>> On Aug 29, 2025, at 2:43 PM, Levo D via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>
>>> The goal of my proposal is to have all bounds be checked at compile time. If I were including containers, the check would be for all containers (and arrays).
>>> I haven't seen "hardened preconditions," but glancing at P3471R0, it looks like it's a runtime check, which isn't my goal.
>>
>> If the bounds and index are known constants at runtime the will be removed. If the bounds and/or index are not known/guaranteed the check _must_ be at runtime. That’s fundamentally unavoidable.
>>
>>> There isn't anything I could add to that. It'd be helpful if that proposal went through, since there might be a lot of changes inside a code base for access to be provably in bounds.
>>> Off the top of my head, there might not be too many changes in my current one and one for containers.
>>
>> It sounds like what you want is a _dianostic_ for trivial cases, which is already present in clang (it’s a warning by default, but you can turn it into an error with -Werror=array-bounds).
>>
>> Slices as you’re proposing aren’t like to happen because the path to memory safety requires moving away from C arrays and pointers as they simply do not have bounds information, and in most cases the information available can't be relied on - this is why despite their best efforts -fbounds-safety can easily require quite a lot of annotations.
>>
>> The correct thing to do is use things like std::span and similar.
>
> The proposal has code that gcc will compile that goes out of range with a literal with no warning.

If you use the hardened runtime - unless you aren't enabling the hardened runtime (which seems possible given the recency, you may need to assert it is available) - it is a bug if it permits the out of bounds access.

_if_ you are saying that you are not getting an error or warning at runtime, that is not the same, and is a task for static analysis.

> Some people don't use std (embedded and games), so I would rather have array support so they have some safety

If you are not using containers, you cannot get safety because you do not have it.

> The proposal has text on how to check if a runtime variable is always in range at compile time (using control flow)

Which fails trivially, so you get a pile of warnings and errors at compile time that falsely imply there is no out of bounds behavior, and at runtime you get real errors anyway. But because you are using pointer based arrays there cannot be any real bounds checking at runtime.

Improving compile time diagnostics for various containers does seem like a worth goal, however _trying_ to achieve that with C arrays is a non-starter. They are fundamentally unsafe as specified. There is no ABI sound way to fix this.

You’re asking for control flow analysis, and we already have that in the form of static analyzers, which know and reason about things like std::span *and* can do far more control flow analysis than is possible for normal compilation - exceeding what you are proposing.

>>> The harder part is stating when a container shouldn't have a bounds check (unless I should explicitly name all the containers that should have it).
>>
>> No - if you know the bounds of an object it is _always_ broken to access out of the bounds.
>
> There's code showing that compilers will allow it, even when it's a literal and size is known.

Yes - and if you used a std::array, or a std::span, or a std::vector, or many other types - with the hardened runtime option, sigh - it would correctly fail without a security vulnerability.

If all your accesses are _provably_ within bounds without any logic that is too absurd, unnecessary bounds checks will be removed by any decent compiler at this point.

>>> A map where people may want mapVar[-123] to return a value shouldn't be checked,
>>
>> I’m not sure what you mean? Do you mean std::map<int, ..> or similar? There would not be a bounds check for that: it’s a map, not an array?
>
> Maybe the correct solution is an attribute, which isn't automatic. I was talking about what if the proposal was for containers, and if there was an automatic way to apply checking, but now I think that's likely the wrong move.

I am not sure what you are saying? If they are writing their own containers they can add the bounds checks without worrying about whether or not the hardened runtime is involved?

>>> although I'm unsure if people want me to include a case for maps where we need to check if a key exists before using it that way.

I think there are many cases, the existing ergonomics are really awful, but that’s a completely different misery pit, that is arguably easier to deal with (because people are less inexplicably horrified by the idea checking the content of a map, than they are about bounds safety despite multiple decades of security vulnerabilities due to the absence).

—Oliver



Received on 2025-08-30 01:23:47