[CC += Kees, Andrew]

[start of thread: 
<https://inbox.sourceware.org/gcc/ac2550e0-2f5c-3680-08e6-0c224d043...@gmail.com/T/#u>]

On 5/11/23 18:07, Alejandro Colomar wrote:
> 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[];
>       |                            ^~~~
> 
> 

Currently, the Linux kernel has to go through some hoops due to this
restriction:


$ grepc -tm __DECLARE_FLEX_ARRAY *
include/uapi/linux/stddef.h:42:
#define __DECLARE_FLEX_ARRAY(TYPE, NAME)        \
        struct { \
                struct { } __empty_ ## NAME; \
                TYPE NAME[]; \
        }


tools/include/uapi/linux/stddef.h:42:
#define __DECLARE_FLEX_ARRAY(TYPE, NAME)        \
        struct { \
                struct { } __empty_ ## NAME; \
                TYPE NAME[]; \
        }
$ grep -rnB2 __DECLARE_FLEX_ARRAY * | head
include/uapi/rdma/rdma_user_rxe.h-153-  __u32                   reserved;
include/uapi/rdma/rdma_user_rxe.h-154-  union {
include/uapi/rdma/rdma_user_rxe.h:155:          __DECLARE_FLEX_ARRAY(__u8, 
inline_data);
include/uapi/rdma/rdma_user_rxe.h:156:          __DECLARE_FLEX_ARRAY(__u8, 
atomic_wr);
include/uapi/rdma/rdma_user_rxe.h:157:          __DECLARE_FLEX_ARRAY(struct 
rxe_sge, sge);
--
include/uapi/scsi/scsi_netlink_fc.h-53- union {
include/uapi/scsi/scsi_netlink_fc.h-54-         __u32 event_data;
include/uapi/scsi/scsi_netlink_fc.h:55:         __DECLARE_FLEX_ARRAY(__u8, 
event_data_flex);
--




-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to