C++ PATCH to reject initializating flexible array members in constructors (PR c++/72775)

Martin Sebor msebor@gmail.com
Fri Dec 9 16:33:00 GMT 2016

On 12/09/2016 08:34 AM, Nathan Sidwell wrote:
> On 12/09/2016 10:18 AM, Martin Sebor wrote:
>> On 12/09/2016 08:09 AM, Jakub Jelinek wrote:
>>> On Fri, Dec 09, 2016 at 08:04:11AM -0700, Martin Sebor wrote:
>>>> then (IMO) so is this:
>>>>   struct Foo {
>>>>    int a;
>>>>    char ary[];
>>>>    Foo () : ary ("bob") {}
>>>>   };
>>> So what does this mean?  Assume that the Foo object lives on the heap
>>> and has been allocated with extra space after it?  Or shall
>>> global/automatic
>>> objects of type Foo be allocated with the extra space (like
>>> struct Foo x = { 5, "bob" }; in C would do if the Foo () ... line is
>>> removed?
>>> Something different?
>> It means the same thing as the first case, down to sizeof (Foo).
>> All of Foo's ctors would have to agree on the size of the initializer
> 1) if the ctors are not defined in the structure definition, how will
> this interact with separate compilation? (all the ctor definitions might
> be in TUs not visible from the TU calling them)

Right.  We would have to decide how to deal with it.  One way might
be to error out/warn if not all the ctors were visible and the array
were not (also) initialized in the class, to avoid undefined behavior.

> 2) why distinguish this case from the NSDMI case?  NSDMI is essentially
> syntactic sugar to avoid repeating the ary member init in each ctor.

Agreed.  I'm suggesting the opposite: i.e., to treat these cases
the same, with the NSDMI syntax being preferred and the ctor member
initializer syntax being subject to some reasonable limitations to
avoid undefined behavior.

> 3) where in C++ is the layout of an object determined by anything other
> than its data member definitions?

Off the top of my head I can't think of any existing cases  but one
was proposed(*) that allowed

   struct Foo {
       auto i = 0;
       auto a = "abc";

For flexible array members, because they're not in C++, we get to
make up the rules that make the most sense to us.  IMO, they should
fit in well with the rest of the language.  Because the bound of
a non-member array can be omitted and its size determined from its
initializer, extending the same rule to [flexible] array members
feels natural to me (but YMMV).


[*] The feature ended up getting removed from the NSDMI proposal,
IIRC, out of concern about making it all too easy to change the
layout of a class and violating the ODR.  (The same ODR concern
could be raised with non-member uses of auto, or with any number
of other C++ features.)

More information about the Gcc-patches mailing list