Name
        alx-0078r2 - [static n] shouldn't access more than n elements

Principles
        -  Uphold the character of the language.
        -  Codify existing practice to address evident deficiencies.
        -  Enable secure programming.

        And from previous charters:

        C23:
        -  APIs should be self-documenting when possible.

Category
        Language; array parameters.

Authors
        Alejandro Colomar <[email protected]>
        Martin Uecker <[email protected]>

        Acked-by: Doug McIlroy
        Acked-by: Andrew Clayton <[email protected]>

History
        <https://www.alejandro-colomar.es/src/alx/alx/std/wg14/alx-0078.git/>

        r0 (2026-01-25):
        -  Initial draft.

        r1 (2026-01-25):
        -  wfix.
        -  Co-authored by Martin.

        r2 (2026-01-26):
        -  Acked-by.
        -  tfix

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.

Prior art
        GCC acknowledges this common understanding, and diagnoses such
        code:

                alx@devuan:~/tmp$ cat ap.c 
                void g(int a[static 3]);
                void f(int a[static 2])
                {
                        g(a);
                }
                alx@devuan:~/tmp$ gcc -S ap.c 
                ap.c: In function ‘f’:
                ap.c:4:9: warning: ‘g’ accessing 12 bytes in a region of size 8 
[-Wstringop-overflow=]
                    4 |         g(a);
                      |         ^~~~
                ap.c:4:9: note: referencing argument 1 of type ‘int[3]’
                ap.c:1:6: note: in a call to function ‘g’
                    1 | void g(int a[static 3]);
                      |      ^

Future directions
        [n] should have the same properties regarding array bounds,
        thereby acknowledging the common understanding of what [n]
        means.  This will be addressed by a future proposal.

Comments
        On 2026-01-25T18:19:02-0500, Douglas McIlroy wrote:
        > All six proposals look eminently reasonable.  They simplify
        > the language and remove surprises.  I suspect these proposals
        > will invalidate very few existing programs.  In any event, the
        > required corrections will improve the legibility and
        > maintainability of such programs.
        >
        > Doug McIlroy

        ---

        On 2026-01-26T02:01:16+0000, Alex Celeste wrote:
        > Like Martin - these all seem eminently reasonable to me.

Proposed wording
        Based on N3685.

    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.

        ## Editorially replace s/size/array length/ while at this.

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

Attachment: signature.asc
Description: PGP signature

Reply via email to