Hi! Currently, one can have pseudo-flexible array members in unions with [0] syntax, but it's not allowed with [] syntax.
Here's an example of how it is possible today:
struct s {
...
size_t n;
union {
ptrdiff_t off[0]; // [n]; offsets from s->data.
char data[0];
};
};
which is useful to have a structure with two (or really several)
consecutive flexible arrays: one of offsets, which mark the positions
of data, and another with the actual data. Below goes an example
program, which works fine with GCC, and I believe rewriting it to
not use the union would make it less clear, since I'd need to add
casts to it.
It works thanks to [0] pseudo-flexible arrays, but it doesn't
compile with C99 flexible arrays. And of course, [0] arrays have
issues with -fstrict-flex-arrays=3.
$ cat flexi4.c
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct s {
size_t n;
union {
ptrdiff_t off[0];
char data[0];
};
};
int
main(void)
{
char *p;
struct s *s;
s = malloc(offsetof(struct s, off) +
sizeof(ptrdiff_t) * 2 +
sizeof("foobar") + sizeof("baz"));
s->n = 2;
p = s->data + sizeof(ptrdiff_t) * s->n;
s->off[0] = p - s->data;
p = stpcpy(p, "foobar") + 1;
s->off[1] = p - s->data;
p = stpcpy(p, "baz") + 1;
puts(s->data + s->off[0]);
puts(s->data + s->off[1]);
free(s);
}
$ gcc-13 -Wall -Wextra -Werror -fanalyzer \
-fsanitize=undefined -fsanitize=address \
-D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=2 \
flexi4.c
$ ./a.out
foobar
baz
$ gcc-13 -Wall -Wextra -Werror -fanalyzer \
-fsanitize=undefined -fsanitize=address \
-D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=3 \
flexi4.c
$ ./a.out
flexi4.c:27:8: runtime error: index 0 out of bounds for type 'ptrdiff_t [*]'
flexi4.c:29:8: runtime error: index 1 out of bounds for type 'ptrdiff_t [*]'
flexi4.c:32:23: runtime error: index 0 out of bounds for type 'ptrdiff_t [*]'
foobar
flexi4.c:33:23: runtime error: index 1 out of bounds for type 'ptrdiff_t [*]'
baz
Would you allow flexible array members in unions? Is there any
strong reason to disallow them?
Currently, I get:
$ gcc-13 -Wall -Wextra -fanalyzer \
-fsanitize=undefined -fsanitize=address \
-D_FORTIFY_SOURCE=3 -fstrict-flex-arrays=3 \
flexi4-true.c
flexi4-true.c:9:28: error: flexible array member in union
9 | ptrdiff_t off[];
| ^~~
flexi4-true.c:10:28: error: flexible array member in union
10 | char data[];
| ^~~~
Cheers,
Alex
--
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5
OpenPGP_signature
Description: OpenPGP digital signature
