This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [c++] RFC: partial C99 designated-initializers support


On Mon, 25 Oct 2004, Andreas Schwab wrote:

> Mark Mitchell <mark@codesourcery.com> writes:
> 
> > What does C99 say should happen in this case:
> >
> >   int i[] = { [3] = 7, [2] = i[3] };
> >
> > ?
> 
> I don't think this is valid because i does not have a complete type until
> after the initializer.

You can access elements of an array declared with an incomplete type.

The order of subobject initialization is initializer list order (though it 
isn't entirely clear whether this is specified as an execution order or 
only as a precedence order for the purposes of initializers overriding 
earlier ones), but the order of evaluation of initializers is unspecified; 
there also appears to be no ordering between the evaluation of one 
initializer and the initialization of another element (beyond the obvious 
that before an element is initialized, the previous (in initializer list 
order) ones have been and so their initializers have been evaluated), and 
no ordering specifying when the default zero initialization of 
uninitialized elements happens.

I think each of the following is a valid way to execute designated 
initializers:

* Evaluate all initializers (in any order, and optionally ignoring 
overridden ones; the sequence point at the end of an initializer doesn't 
separate it from the other ones in that list), then initialize the object 
with them (in initializer list order, but the as-if rule means different 
orders can't be distinguished).  I think this is essentially what GCC 
does; the C front end discards overridden initializers, and the gimplifier 
creates temporaries as necessary when evaluating initializer elements.

* Evaluate the initializers in sequence, initializing each subobject after 
its initializer is evaluated and zero-initializing uninitialized objects 
when the relevant braces are closed, or when they are opened.

You might be safely able to initialize an element with the previous value 
of one *later* in the initializer list

  int first_time = 1;
  l:;
  int i[] = { [2] = (first_time ? 1 : i[1]), [1] = 2, [0] = 3 };
  first_time = 0;
  goto l;

as the initialization of i[1] can only take place after the sequence point 
at the end of the initializer for i[2], but I think the example

> >   int i[] = { [3] = 7, [2] = i[3] };

given is undefined because there is no sequence point between the 
initialization of i[3] and the evaluation of the initializer for i[2].

If anyone produces a specific proposal to include designated initializers 
in C++0x then they'll need to deal with the destructor order issue.  
Without such a proposal, perhaps they should be limited to POD types in 
C++, though I don't know offhand if that suffices to avoid all problems 
with the definition of their semantics in C++.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]