On Sun, 7 May 2006, Neil Booth wrote:

> My front end, and Comeau's oneline compiler, both give a similar
> message:
> 
> "/tmp/foo.c", line 10: error: expression must point to a complete type
>   int r = (c1()
>           ^
> 
> which seems reasonable based on my understanding of composite types
> of VLA types: that either satisfies the requirements of, and therefore
> can be taken to be, the composite type.

I think the type's complete: the recursive application of the composite 
type rules means that the composite of each [] and [VLA] pair is the 
[VLA], yielding a composite type int (*(*(*)[d1()])[d2()])[d3()]; the 
trouble being that d1(), d2() and d3() won't all have been evaluated when 
the composite type is required.

(My model is that each array size expression initializes an implicit 
temporary variable, and my example involves runtime access to those 
variables while some are uninitialized.)

I think you only have free choice in composites of VLA types when 
compositing [VLA1] and [VLA2], where if at runtime the two are unequal 
then you have undefined behavior.  (Given that one of [VLA1] and [VLA2] 
might not be evaluated, and likewise when compositing [CONSTANT] and 
[VLA], problems arise in those cases as well.  My best suggested fix was: 
6.7.5.2 pargraph 6 at end add "or one of the size specifiers (including 
the case of a single size specifier where the other array type does not 
include a size specifier) is not an integer constant expression and is not 
evaluated during the flow of execution.")

If, instead of embedding the types in the expression, they were previously 
defined as typedefs, so all the array size expressions had been evaluated, 
I would say the code is well-defined.

        int a, b, c, d, e, f;
        void *p1(void), *p2(void), *p3(void);
        int c1(void), c2(void);
        int d1(void), d2(void), d3(void);
        int z1(void), z2(void), z3(void);

        int
        h(void)
        {
          typedef int (*(*(*T1)[d1()])[])[];
          typedef int (*(*(*T2)[])[d2()])[];
          typedef int (*(*(*T3)[])[])[d3()];
          int r = (c1()
                   ? (z1(), (T1)p1())
                   : (c2()
                      ? (z2(), (T2)p2())
                      : (z3(), (T3)p3())
                     )
                  )[a][b][c][d][e][f];
          return r;
        }

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    [EMAIL PROTECTED] (personal mail)
    [EMAIL PROTECTED] (CodeSourcery mail)
    [EMAIL PROTECTED] (Bugzilla assignments and CCs)

Reply via email to