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[])
  { }
// ------------------------------------------------------

Reply via email to