N3242 8.5.1/15 -- braced union declarations limited only to first member

157 views
Skip to first unread message

rick.c...@googlemail.com

unread,
Aug 30, 2014, 2:30:01 PM8/30/14
to

Taken from:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

----------
8.5.1 / 15 When a union is initialized with a brace-enclosed initializer,
the braces shall only contain an initializer-clause for the first non-
static data member of the union.

[ Example:
union u { int a; const char* b; };
u a = { 1 };
u b = a;
u c = 1; // error
u d = { 0, "asdf" }; // error
u e = { "asdf" }; // error
--end example ]

----------
Why?

Such a decision severely hobbles the use of unions, limiting their full
functionality to run-time code, and in a case where compile-time non-first
member initialization is more than just possible, it's almost trivial.

I'm thinkin' ... I can't see the reasonin' ... Please help me out.

Gracias. :-)

Best regards,
Rick C. Hodgin


--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp...@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Rick C. Hodgin

unread,
Sep 16, 2014, 10:10:03 PM9/16/14
to

On Saturday, August 30, 2014 2:30:01 PM UTC-4, Rick C. Hodgin wrote:
> Taken from:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
>
> ----------
> 8.5.1 / 15 When a union is initialized with a brace-enclosed initializer,
> the braces shall only contain an initializer-clause for the first non-
> static data member of the union.
>
> [ Example:
> union u { int a; const char* b; };
> u a = { 1 };
> u b = a;
> u c = 1; // error
> u d = { 0, "asdf" }; // error
> u e = { "asdf" }; // error
> --end example ]
>
> ----------


If no one objects, I propose this limitation be removed and replaced
with an allowance for compile-time initializer clauses to any union
member.

Philip Guenther

unread,
Sep 17, 2014, 8:30:03 PM9/17/14
to

On Tuesday, September 16, 2014 7:10:03 PM UTC-7, Rick C. Hodgin wrote:
> On Saturday, August 30, 2014 2:30:01 PM UTC-4, Rick C. Hodgin wrote:
> > Taken from:
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
> >
> > ----------
> > 8.5.1 / 15 When a union is initialized with a brace-enclosed initializer,
> > the braces shall only contain an initializer-clause for the first non-
> > static data member of the union.
> >
> > [ Example:
> > union u { int a; const char* b; };
> > u a = { 1 };
> > u b = a;
> > u c = 1; // error
> > u d = { 0, "asdf" }; // error
> > u e = { "asdf" }; // error
> > --end example ]
> > ----------
>
>
> If no one objects, I propose this limitation be removed and replaced
> with an allowance for compile-time initializer clauses to any union
> member.

Don't C99 designated initializers solve this problem?


Philip Guenther

Rick C. Hodgin

unread,
Sep 19, 2014, 2:10:02 AM9/19/14
to

On Wednesday, September 17, 2014 8:30:03 PM UTC-4, Philip Guenther wrote:
> On Tuesday, September 16, 2014 7:10:03 PM UTC-7, Rick C. Hodgin wrote:
> > If no one objects, I propose this limitation be removed and replaced
> > with an allowance for compile-time initializer clauses to any union
> > member.
>
> Don't C99 designated initializers solve this problem?

I would like the compiler to determine the union member by its type
when possible.

struct SExample
{
int i;
float f;
};

SExample myArray[] = {
{ 10 }, // Initialized to i member as int
{ 3.14f } // Initialized to f member as float
};

No designators, but rather by initializer type the appropriate member
is populated into. And if it is ambiguous, such as using 5 for a union
containing both int and char members, then it must be explicitly cast,
or a designator must be used.

Best regards,
Rick C. Hodgin


James Kuyper

unread,
Sep 19, 2014, 2:10:06 AM9/19/14
to

On 09/17/2014 09:29 PM, Philip Guenther wrote:
>
> On Tuesday, September 16, 2014 7:10:03 PM UTC-7, Rick C. Hodgin wrote:
>> On Saturday, August 30, 2014 2:30:01 PM UTC-4, Rick C. Hodgin wrote:
>>> Taken from:
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
>>>
>>> ----------
>>> 8.5.1 / 15 When a union is initialized with a brace-enclosed initializer,
>>> the braces shall only contain an initializer-clause for the first non-
>>> static data member of the union.
>>>
>>> [ Example:
>>> union u { int a; const char* b; };
>>> u a = { 1 };
>>> u b = a;
>>> u c = 1; // error
>>> u d = { 0, "asdf" }; // error
>>> u e = { "asdf" }; // error
>>> --end example ]
>>> ----------
>>
>>
>> If no one objects, I propose this limitation be removed and replaced
>> with an allowance for compile-time initializer clauses to any union
>> member.
>
> Don't C99 designated initializers solve this problem?

They would, and changing C++ to support them would be a better approach
than the one suggested above.
--
James Kuyper

Francis Glassborow

unread,
Sep 19, 2014, 2:10:09 AM9/19/14
to

On 18/09/2014 02:29, Philip Guenther wrote:
>
>
> On Tuesday, September 16, 2014 7:10:03 PM UTC-7, Rick C. Hodgin wrote:
>>
>> On Saturday, August 30, 2014 2:30:01 PM UTC-4, Rick C. Hodgin wrote:
>>>
>>> Taken from:
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
>>>
>>> ----------
>>> 8.5.1 / 15 When a union is initialized with a brace-enclosed initializer,
>>> the braces shall only contain an initializer-clause for the first non-
>>> static data member of the union.
>>>
>>> [ Example:
>>> union u { int a; const char* b; };
>>> u a = { 1 };
>>> u b = a;
>>> u c = 1; // error
>>> u d = { 0, "asdf" }; // error
>>> u e = { "asdf" }; // error
>>> --end example ]
>>> ----------
>>
>>
>>
>> If no one objects, I propose this limitation be removed and replaced
>> with an allowance for compile-time initializer clauses to any union
>> member.
>
>
> Don't C99 designated initializers solve this problem?


But this is C++

Francis

Rick C. Hodgin

unread,
Sep 20, 2014, 2:40:02 AM9/20/14
to

Should have been:

-----
I would like the compiler to determine the union member by its type
when possible.

struct SExample
{
union {
int i;
float f;
};
};

SExample myArray[] =
{
{ 10 }, // Initialized to i member as int
{ 3.14f } // Initialized to f member as float
};

Also, on conflicting types, such as 5 for int and
char, if the bytes they occupy would all map to
the same location in the union, the cast would
not be required.

Martin Bonner

unread,
Sep 23, 2014, 4:00:02 PM9/23/14
to

On Saturday, 20 September 2014 07:40:02 UTC+1, Rick C. Hodgin wrote:
> Should have been:
> -----
> I would like the compiler to determine the union member by its type
> when possible.
>
> struct SExample
> {
> union {
> int i;
> float f;
> };
> };
>
> SExample myArray[] =
> {
> { 10 }, // Initialized to i member as int
> { 3.14f } // Initialized to f member as float
> };
>
> Also, on conflicting types, such as 5 for int and
> char, if the bytes they occupy would all map to
> the same location in the union, the cast would
> not be required.

That would be a terrible idea! It means that code would
compile on a little-endian machine, but not a big-endian one.
(For example)


I agree that C99 designated initializers would be a much
better solution:
- They have already been cast into standardese.
- If gcc doesn't support them for C++, it's probably not hard to
make it do so (so we can gain implementation experience).
- They would be of more general utility than just initializing
unions.

Rick C. Hodgin

unread,
Sep 24, 2014, 5:40:01 PM9/24/14
to

On Tuesday, September 23, 2014 4:00:02 PM UTC-4, Martin Bonner wrote:
> On Saturday, 20 September 2014 07:40:02 UTC+1, Rick C. Hodgin wrote:
> > Also, on conflicting types, such as 5 for int and
> > char, if the bytes they occupy would all map to
> > the same location in the union, the cast would
> > not be required.
>
> That would be a terrible idea! It means that code would
> compile on a little-endian machine, but not a big-endian one.
> (For example)

I think to remove it from allowance would place an excessive and
unnecessary burden on every little-endian developer, demanding
that they cast everything explicitly when it's not needed for
their architecture. Not every developer writes cross-architecture
code.

And there are and should be some penalties big-endian developers pay
for their choices. The burden should be on THOSE developers, and not
on ALL developers because of shortcomings in their architecture. :-)

> I agree that C99 designated initializers would be a much
> better solution:
> - They have already been cast into standardese.
> - If gcc doesn't support them for C++, it's probably not hard to
> make it do so (so we can gain implementation experience).
> - They would be of more general utility than just initializing
> unions.

I agree that designated initializers should be available. I think
that would be a great feature.

I also think that requiring designated initializers places an excessive
and unnecessary burden on EVERY developer when the underlying fundamental
initializer is unambiguous and could be populated correctly by value
alone, or could be correctly mapped as on little-endian architectures,
or even on some big-endian combinations also mapped (char to int, for
example, could be mapped merely by being offset by 3 bytes in the data).

Best regards,
Rick C. Hodgin


Reply all
Reply to author
Forward
0 new messages