On 12/9/22 21:19, Alejandro Colomar wrote: > Hi Martin, > > On 12/9/22 21:04, msebor@gmail.com wrote: >> >> Most of these warnings are designed to find simple mistakes in common use >> cases so "tricky," unusual, or otherwise unexpected code is likely to lead to >> surprises.  This warning expects that in calls to a function, every parameter >> declared using the array syntax (which is expected to have a nonzero bound) is >> passed a dereferenceable pointer as an argument.  It considers neither the >> definition of the function to see if it does in fact dereference the argument, >> nor this unlikely (and strictly invalid) use case. > > Hi Martin, > > Is it really invalid?  AFAIK, ISO C doesn't specify anything for array syntax in > function parameters othen than that they are equivalent to a pointer.  The only > exception is when using 'static', which requires a minimum of 0. Oops, typo there. I wanted to say that 'static' requires a minimum of 1. >  So, [0], by > not using 'static', is conforming code, I believe.  Or does the restriction to > 0-sized arrays also apply to function parameters?  What if you pass a size of 0 > through a variable?  I don't think it's undefined behavior to do so. > > Could you please quote the standard about being "strictly invalid"? > > Cheers, > > Alex > >> >> The warning should not be issued if the parameter is declared as an ordinary >> pointer > > I confirm; it doesn't warn. > >> so I would suggest to use that instead.  It's possible that declaring the >> array parameter with attribute access none might also suppress the warning, >> but there is no utility in using a zero-length array in this context.  The >> intended purpose of the zero-length array GCC extension is as trailing members >> of structs in legacy (pre-C99 code) that cannot use flexible array members. >> Using them anywhere else is likely to be surprising, both to tools and to >> readers, so the attribute on a pointer parameter would be preferable. > > Heh, then the following function will blow brains :P > > > char * > stpecpy(char *dst, const char *restrict src, char past_end[0]) > { >     char *p; > >     if (dst == past_end) >         return past_end; > >     p = memccpy(dst, src, '\0', past_end - dst); >     if (p != NULL) >         return p - 1; > >     /* truncation detected */ >     past_end[-1] = '\0'; >     return past_end; > } > > which similar to strscpy(9), but allows chaining. > > In this case, I can't even use the access attribute.  I _need_ to use the > 'past_end' pointer to access the array (or perform unnecessary pointer > arithmetic that would hurt readability: 'p = &dst[past_end - dst];'). > > > For the curious, a variant that behaves like strlcpy(3), can be implemented as: > > inline char * > stpecpyx(char *dst, const char *restrict src, char past_end[0]) > { >     if (src[strlen(src)] != '\0') >         raise(SIGSEGV); > >     return stpecpy(dst, src, past_end); > } > > > Cheers, > > Alex > --