Short description: the compiler issues spurious warning/errors when an empty array is passed to a procedure, even though that procedure may not access any element of the array.
Output of uname -a: Linux baikal 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Compile command: PROG=c-empty-array-bug /usr/bin/gcc -o ${PROG} \ -Wall -Werror=stringop-overflow ${PROG}.c ./${PROG} Source code (also attached): // ------------------------------------------------------ // Last edited on 2024-11-20 02:46:39 by stolfi #include <stdio.h> void proc(unsigned n, int vc[], char *tb[]); int main (void) { unsigned n = 0; int vector[n]; char *table[n]; int vnext; fprintf(stderr, "vector = %p table = %p vnext = %p\n", (void*)vector, (void*)table, (void*)(&vnext)); proc(n, vector, table); return 0; } void proc(unsigned n, int vc[], char *tb[]) { } // ------------------------------------------------------ Compiler output (with extra "\" to break long lines): // ------------------------------------------------------ c-empty-array-bug.c: In function 'main': c-empty-array-bug.c:17:3: error: 'proc' accessing 4 bytes \ in a region of size 0 [-Werror=stringop-overflow=] 17 | proc(n, vector, table); | ^~~~~~~~~~~~~~~~~~~~~~ c-empty-array-bug.c:17:3: note: referencing argument 2 \ of type 'int[0]' c-empty-array-bug.c:17:3: error: 'proc' accessing 8 bytes \ in a region of size 0 [-Werror=stringop-overflow=] c-empty-array-bug.c:17:3: note: referencing argument 3 \ of type 'char *[0]' c-empty-array-bug.c:21:6: note: in a call to function 'proc' 21 | void proc(unsigned n, int vc[], char *tb[]) | ^~~~ cc1: some warnings being treated as errors // ------------------------------------------------------ Observations: The program seems to be quite valid since the procedure does not reference any element of the two arrays. If the call to proc is commented out, the program compiles and runs without any warning, and produces the output vector = 0x7ffe658b80a0 table = 0x7ffe658b80a0 \ vnext = 0x7ffe658b80a0 Note that the addresses are valid (not NULL). The call to {proc} should just pass those addresses as the vc and tb arguments. All the best, --stolfi -- Jorge Stolfi - Professor Titular/Full Professor Instituto de Computação/Computer Science Dept Universidade Estadual de Campinas/State University of Campinas Campinas, SP - Brazil
// ------------------------------------------------------ // Last edited on 2024-11-20 02:49:08 by stolfi #include <stdio.h> void proc(unsigned n, int vc[], char *tb[]); int main (void) { unsigned n = 0; int vector[n]; char *table[n]; int vnext; fprintf(stderr, "vector = %p table = %p vnext = %p\n", (void*)vector, (void*)table, (void*)(&vnext)); /* proc(n, vector, table); */ return 0; } void proc(unsigned n, int vc[], char *tb[]) { } // ------------------------------------------------------