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/>
> 
> 
> 

Reply via email to