Hi Joseph, > Date: 2026-10-07 21:31:03+0000 > From: Joseph Myers <[email protected]> > > On Wed, 7 Oct 2026, Alejandro Colomar wrote: > > > The strict rules would be that it's a constraint to have the forward > > declaration of a parameter contradict the declaration, and thus a > > constraint violation. However, implementing those diagnostics would be > > non-trivial for me. > > My suggestion would be to be strict on the new feature (e.g. disallow > _Countof for any parameter for which both a forward declaration and > another declaration of the parameter are visible) rather than adding extra > checks for consistency of forward parameter declarations.
That'd be unacceptable for me. I need to be able to use _Countof() on
arrays that have been forward declared.
Here's are a couple of examples:
char *
vseprintf(char dst[], const char end[];
char dst[dst?end-dst:0], const char end[0], const char *restrict
fmt, va_list ap)
{
int len;
ptrdiff_t size;
if (dst == NULL)
return NULL;
len = vstprintf(dst, _Countof(dst), fmt, ap);
if (len == -1)
return NULL;
return dst + len;
}
char *
stpecpy(char dst[], const char end[];
char dst[dst?end-dst:0], const char end[0], const char *restrict
src)
{
ssize_t dlen;
if (dst == NULL)
return NULL;
dlen = strtcpy(dst, src, _Countof(dst));
if (dlen == -1)
return NULL;
return dst + dlen;
}
But we could have a different constraint which I'd find acceptable:
- Disallow declaring any array length expressions within a forward
declaration of a parameter.
void f(int a[42]; int a[]); // constraint violation
void g(int a[42]; int a[42]); // constraint violation
void g(int a[]; int a[42]); // ok
> > int
> > g(int n, int m, int a[][n]; int n, int m, int a[][m])
> > {
> > return _Countof(a[0]);
>
> The cases of concern to me are where the length of the parameter array
> itself might vary between the declarations (or one declaration might be a
> pointer and another an array), because those are the ones where the new
> extension of _Countof on array parameters actually comes into play and
> starts interacting with forward declarations.
>
> This example is using _Countof on something that has array type in the
> existing language for all purposes - not on an array parameter that's
> adjusted to a pointer for most purposes. So it already has undefined
> behavior at runtime if the two declarations (adjusted to pointer-to-array
> type) specify different lengths n and m, and that doesn't depend on the
> use of _Countof, only on the function being called with n != m.
Consistency between arrays and array parameters is what I'm seeking.
I understand you are afraid of adding UB for something which has been
always allowed (IMO, by a historical mistake). So, the viable
alternatives are unspecified behavior, which is like UB but more
benevolent, or a constraint that is acceptable to all of us. The
constraint you specified is unacceptable for me, but maybe my constraint
counter-proposal is acceptable to you (and Martin)?
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
