On Tue, 13 Dec 2022, 19:23 Paul Koning via Gcc, <gcc@gcc.gnu.org> wrote: > > > > > On Dec 13, 2022, at 2:08 PM, Alejandro Colomar via Gcc <gcc@gcc.gnu.org> > > wrote: > > > > Hi! > > > > For the following program: > > > > > > $ cat buf.c > > #include <stdio.h> > > > > int main(void) > > { > > char *p, buf[5]; > > > > p = buf + 6; > > printf("%p\n", p); > > } > > > > > > There are no warnings in gcc, as I would expect: > > > > $ gcc -Wall -Wextra buf.c -O0 > > > > Clang does warn, however: > > > > $ clang -Weverything -Wall -Wextra buf.c -O0 > > buf.c:8:17: warning: format specifies type 'void *' but the argument has > > type 'char *' [-Wformat-pedantic] > > printf("%p\n", p); > > ~~ ^ > > %s > > buf.c:7:6: warning: the pointer incremented by 6 refers past the end of > > the array (that contains 5 elements) [-Warray-bounds-pointer-arithmetic] > > p = buf + 6; > > ^ ~ > > I thought void * is a generic pointer that accepts any pointer argument.
Yes, but printf doesn't take a void* argument. > > So a warning about char* being passed in seems to be flat out wrong. I wouldn't say flat out wrong. It's wrong because the C standard guarantees that void* and char* have the same representation and alignment requirements, so no conversion is needed to pass a char* through a varargs ellipsis where a void* is expected. But if it was int* or struct X* then the warning would be correct (but not a problem in practice on common arches, which is why Clang only enabels it with -Wformat-pedantic). > > > buf.c:5:2: note: array 'buf' declared here > > char *p, buf[5]; > > ^ > > 2 warnings generated. > > That was discussed just days ago: C says that a pointer one past the end of > the array is legal. So here too it looks like Clang is wrong and GCC is > right. No, clang is totally right here.