Hi Alex,
Am Sonntag, dem 04.08.2024 um 19:49 +0200 schrieb Alejandro Colomar:
> Hi Martin,
>
> On Sun, Aug 04, 2024 at 06:43:46PM GMT, Alejandro Colomar wrote:
> > On Sun, Aug 04, 2024 at 06:40:14PM GMT, Alejandro Colomar wrote:
> > > > The lastÂ
> > > > case should return a non-constant.
> > >
> > > The last case [*] is only allowed in prototypes. How should we get the
> > > non-constant value? It's just another way to say [], isn't it?
> > >
> > > > If you reuse the sizeof code, it should be mostly correct, but
> > > > maybe the last case needs to be revisted. In the following
> > > > examples
> > > >
> > > > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > > > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > > >
> > > > the array '*x' should be a regular fixed size array in foo
> > > > but a VLA in 'bar'.
> > >
> > > In the function prototype, it seems to be completely ignoring
> > > __lengthof__, just as it ignores any expression, so I don't know if it's
> > > working (I could try to print some debugging values to stderr from the
> > > compiler, if we care about it).
> >
> > Huh, no, my bad. It must be using the lengthof value. It needs to
> > match pointers to arrays of a given size. I'll test this.
>
> Is this missing diagnostics?
>
> $ cat star.c
> void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> void foos(char (*a)[3][*], int (*x)[sizeof(*a)]);
> void bars(char (*a)[*][3], int (*x)[sizeof(*a)]);
>
> int
> main(void)
> {
> int i3[3];
> int i5[5];
> char c35[3][5];
> char c53[5][3];
>
> foo(&c35, &i3);
> foo(&c35, &i5); // I'd expect this to fail
Yes, this should fail. The int (*)[5] is not
compatible with int(*)[3].
> bar(&c53, &i3); // I'd expect this to fail
This is no contraint violation, because int (*)[5] is
compatible with int (*i)[*], so this needs to be accepted.
It is then UB at run-time and the patches I posted recently
would catch this. When possible, a compile time warningÂ
would be nice and I am also looking into this.
It would also be good if we could allow a compiler to
reject this at compile time... also something I am
thinking about.
> bar(&c53, &i5);
>
> foos(&c35, &i3);
> foos(&c35, &i5); // I'd expect this to fail
> bars(&c53, &i3); // I'd expect this to fail
These are both okay, because the sizeof is not an integer
constant expressions (both int[*][3] and int[3][*] have
variable size), so the last argument has to be compatible
with int[*] which they both are. Both would trigger
run-time UB then because the size is then 15.
Martin
> bars(&c53, &i5);
> }
> $ /opt/local/gnu/gcc/lengthof/bin/gcc -Wall -Wextra star.c -S
> $
>
> Cheers,
> Alex
>
> >
> > >
> > > $ cat muecker.h
> > > void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > > void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > > void f(char (*a)[3][*], int (*x)[sizeof(*a)]);
> > > void b(char (*a)[*][3], int (*x)[sizeof(*a)]);
> > > $ /opt/local/gnu/gcc/lengthof/bin/gcc muecker.h -S
> > > $
> > >
> > > I assume the code above is not reaching my code.
> >
> > --
> > <https://www.alejandro-colomar.es/>
>
>
>