Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Loops (was Re: do { quit; } else { })
Date: Tue, 13 May 2025 18:38:32 -0700
Organization: A noiseless patient Spider
Lines: 102
Message-ID: <86ecwsvunb.fsf@linuxsc.com>
References: <20250415153419.00004cf7@yahoo.com> <86h62078i8.fsf@linuxsc.com> <20250504180833.00000906@yahoo.com> <86plggzilx.fsf@linuxsc.com> <86ldr4yx0x.fsf@linuxsc.com> <1000cs3$2234m$1@dont-email.me> <87sel8nqid.fsf@nosuchdomain.example.com> <86msbgw49b.fsf@linuxsc.com> <875xi4cevz.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Wed, 14 May 2025 03:38:33 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="adcc0210618ce5c814d2d263cc71a7bf";
logging-data="2246136"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+2ENtE7x3/nzW4h8IUnYDUfZMbifaD+Hs="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:n868LTh3LverNEFicIGfqgRagYE=
sha1:pNOl4WRrR2JBpTLN94671eI6nrw=
Bytes: 5226
Keith Thompson writes:
> Tim Rentsch writes:
>
>> Keith Thompson writes:
>
> [...]
>
>>> My personal interpretation is that this:
>>>
>>> void func(int arr[static 5]) {
>>> }
>>>
>>> int main(void) {
>>> int arr[10];
>>> func(arr+5); // OK
>>> // func(arr+6); // UB
>>> }
>>>
>>> is valid, because, for example, the last 5 elements of a 10-element
>>> array object can be treated as a 5-element array object. gcc seems
>>> to agree, based on the fact that it warns about func(arr+6) but
>>> not about func(arr+5).
>>>
>>> This is a fundamental part of my mental model of C, but in a few
>>> minutes of searching I wasn't able to find explicit wording in the
>>> standard that supports it.
>>
>> In N1570, 6.7.6.3 p7.
>
> Did you mean to imply that that paragraph supports (or refutes) my
> statement? [...]
No. I posted the reference to say that the cited paragraph supports
the conclusion that 'func(arr+6)' is undefined behavior.
> """
> 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.
> """
>
> The question is whether, for example, the last 5 elements of a
> 10-element array object can be treated as a 5-element array object.
> If someone can cite wording in the standard that answers that
> question, I'd appreciate it. (I'll be happier if the answer is yes.)
To me it seems obvious that 6.7.6.3 p7 is meant to cover the
case of 'func(arr+6)' as being undefined behavior.
Note that 6.7.6.3 p7 doesn't say "array object", it says just
"array". I believe the choice of wording is neither an accident nor
an oversight.
> Looking into this a bit more, I realize that the question doesn't
> matter if there's no "static" keyword between the [ and ]. In that
> case, the parameter is of pointer type, and the description of
> pointer arithmetic (N1570 6.5.6p8) explicitly allows the pointer
> to point to the i-th element of an array object. The wording for
> [static N] is the only place I've seen (so far) that specifically
> refers to the *first* element of an array object, raising the
> question of whether a subobject of an array object is itself an
> array object.
Again, not an array object, just an array.
> This might just be some slightly sloppy wording that was
> introduced in C99 and never corrected.
I draw the opposite conclusion. The wording of 6.7.6.3 p7 was
carefully chosen so that it would cover cases like 'func(arr+6)'.
> For example, given this code:
>
> ```
> void without_static(int arr[]) {
> (void)arr[4];
> }
>
> void with_static(int arr[static 5]) {
> (void)arr[4];
> }
>
> int main(void) {
> int arr[10] = { 0 };
> without_static(arr+5);
> with_static(arr+5);
> }
> ```
>
> there's no problem with the call `without_static(arr+5)`, but the
> call `with_static(arr+5)` has defined behavior if and only if the
> last 5 elements of a 10-element array object can be treated as a
> 5-element array object.
That isn't what the C standard says. It just says "array", not
"array object".