Macaulay2 / M2

The primary source code repository for Macaulay2, a system for computing in commutative algebra, algebraic geometry and related fields.
https://macaulay2.com
330 stars 226 forks source link

Use flexible array members instead of struct hack #3326

Closed d-torrance closed 6 days ago

d-torrance commented 1 week ago

This fixes the compiler warnings we were getting when trying to allocate empty arrays, e.g.:

CC M2-tmp.c
../../../../Macaulay2/d/M2.d: In function ‘M2__prepare’:
../../../../Macaulay2/d/M2.d:142:9: warning: array subscript ‘struct M2_ArrayString_struct[0]’ is partly outside array bounds of ‘unsigned char[8]’ [-Warray-bounds]
  142 | export argc := 0;
      |         ^~
In file included from ../../../../Macaulay2/d/../../include/M2/gc-include.h:44,
                 from ../../../../Macaulay2/d/../c/scc-core.h:6,
                 from M2-tmp.c:2:
../../../../Macaulay2/d/M2.d:142:29: note: referencing an object of size 8 allocated by ‘GC_malloc’
  142 | export argc := 0;
      |                             ^        
../../../../Macaulay2/d/M2.d:142:9: warning: array subscript ‘struct M2_ArrayString_struct[0]’ is partly outside array bounds of ‘unsigned char[8]’ [-Warray-bounds]
  142 | export argc := 0;
      |         ^~
In file included from ../../../../Macaulay2/d/../../include/M2/gc-include.h:44,
                 from ../../../../Macaulay2/d/../c/scc-core.h:6,
                 from M2-tmp.c:2:
../../../../Macaulay2/d/M2.d:142:29: note: referencing an object of size 8 allocated by ‘GC_malloc’
  142 | export argc := 0;
      |                             ^        
../../../../Macaulay2/d/M2.d:142:9: warning: array subscript ‘struct M2_ArrayString_struct[0]’ is partly outside array bounds of ‘unsigned char[8]’ [-Warray-bounds]
  142 | export argc := 0;
      |         ^~
In file included from ../../../../Macaulay2/d/../../include/M2/gc-include.h:44,
                 from ../../../../Macaulay2/d/../c/scc-core.h:6,
                 from M2-tmp.c:2:
../../../../Macaulay2/d/M2.d:142:29: note: referencing an object of size 8 allocated by ‘GC_malloc’
  142 | export argc := 0;
      |                             ^

The problem was that previously arrays were defined using the "struct hack":

struct M2_string_struct {int len;signed char array[1];};

We then allocated enough memory for the struct (which includes the pointer to the first element of the array) and len - 1 more elements of the array. But when len was 0, this was negative.

We can avoid this by using flexible array members, which were introduced in C99. In particular, now arrays are defined like this:

struct M2_string_struct {int len;signed char array[];};

We now allocate enough memory for the struct and all len members of the array, with no problems when len is 0.

Closes: #2274