Hi Daniel,

On 2026-01-28T09:54:37+0000, Daniel Thompson wrote:
> On Mon, Jan 26, 2026 at 01:48:49PM +0100, Alejandro Colomar wrote:
> > Name
> >     alx-0078r2 - [static n] shouldn't access more than n elements
> >

[...]
> > Abstract
> >     The following function prototype requires an input with at least
> >     2 elements:
> >
> >             void f(int a[static 2]);
> >
> >     It should not use more than 2 elements, as those are not
> >     guaranteed to be available.  That is, the following function
> >     definition should be unacceptable:
> >
> >             void f(int a[static 2])
> >             {
> >                     a[7] = 0;
> >             }
> >
> > Discussion
> >     It is a de-facto standard that functions declaring a [static n]
> >     parameter require at least n elements, and don't access more
> >     than n elements.  Most programmers that don't know the fine
> >     letter of the standard would assume that.  This has its roots in
> >     the older syntax, [n], which is not acknowledged by the
> >     standard, but has been historically used to document this as
> >     part of the API.
> >
> >     Without this, [static n] is only useful for optimizations, but
> >     not for writing safe code, as the specification of [static n]
> >     doesn't provide the compiler with enough information to know
> >     whether array bounds will be violated.  This makes it a terrible
> >     UB foot-gun.
> >
> >     Let's change the specification to make it safe.
> 
> I don't see how the proposed wording change makes C safer, see below.
> 
> 
> >     <snip>
> >     6.7.7.4  Function declarators
> >     @@ Semantics, p7
> >      A declaration of a parameter as "array of type"
> >      shall be adjusted to "qualified pointer to type",
> >      where the type qualifiers (if any)
> >      are those specified
> >      within the [ and ]
> >      of the array type derivation.
> >      If the keyword static also appears
> >      within the [ and ]
> >      of the array type derivation,
> >      then for each call to the function,
> >      the value of the corresponding actual argument
> >      shall provide access to
> >      the first element of an array
> >      with at least as many elements
> >     -as specified by the size expression.
> >     +as specified by the array length expression,
> >     +and the function definition
> >     +shall not access an element
> >     +beyond the specified number of elements.
> 
> By limiting what the function definition may do, we are reducing the set
> of valid programs. Won't that *increase* the level of undefined
> behaviour in the language?

Yes, this proposal increases --at least theoretically-- the amount of
undefined in the language.  See below for why I say "theoretically".

> That will allow compilers to perform more aggressive local optimizations
> (which is probably good) but I don't see how it will make things safer.

Yes, that's true.  On the other hand, nobody is forcing compilers to
abuse UB to perform aggresive optimizations.  They may choose to refrain
from certain optimizations, and instead use the information exclusively
for diagnostics.

> To make things safe would mean compilers changing their diagnostics, and
> the prior art suggests compilers already warn on this.

GCC has partial support for this, precisely because it ignores the
specification of the standard, and de-facto considers this to be the
meaning of [static n] (and also of [n], FWIW).  GCC support for this is
incomplete at the moment, though.  But in the long term, yes, GCC
intends to diagnose like this.

On the other hand, Clang implements this per the C standard, which makes
it a quite bad implementation regarding array bounds.

        alx@devuan:~/tmp$ cat ap.c 
        void f(int a[static 2]);
        void f(int a[static 2])
        {
                a[1] = 0;
                a[2] = 0;  // UB
                a[3] = 0;  // UB
        }
        alx@devuan:~/tmp$ gcc -S ap.c -Wall -Wextra
        alx@devuan:~/tmp$ clang -S ap.c -Weverything
        ap.c:4:2: warning: unsafe buffer access [-Wunsafe-buffer-usage]
            4 |         a[1] = 0;
              |         ^
        ap.c:5:2: warning: unsafe buffer access [-Wunsafe-buffer-usage]
            5 |         a[2] = 0;  // UB
              |         ^
        ap.c:6:2: warning: unsafe buffer access [-Wunsafe-buffer-usage]
            6 |         a[3] = 0;  // UB
              |         ^
        3 warnings generated.

-Wunsafe-buffer-access is just noise.  Nothing is diagnosing the case
shown in the abstract.

The case shown in the 'Prior art' section is only diagnosed by GCC.

So, this proposal would force Clang to diagnose what GCC already
diagnoses.

About why this increase in UB is only theoretical: programs violating
this *already* have UB (with 99.99% certainty).  The UB is just not
visible to the compiler, but the program is already overflowing buffers
most likely.  By making that UB visible to the compiler, we increase the
chances that it will be diagnosed.  So, I'd say I'm not adding UB, but
rather moving it around to show up earlier.


Have a lovely day!
Alex

> Daniel.

-- 
<https://www.alejandro-colomar.es>

Attachment: signature.asc
Description: PGP signature

Reply via email to