Bug 53608 - Documentation could be clearer about designated initializers of unions
Summary: Documentation could be clearer about designated initializers of unions
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: documentation
Depends on:
Blocks:
 
Reported: 2012-06-08 05:05 UTC by Alan Coopersmith
Modified: 2018-11-23 05:40 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alan Coopersmith 2012-06-08 05:05:33 UTC
http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html currently says:

   If the same field is initialized multiple times, it will have value 
   from the last initialization.

(Which should probably say "the value" instead.)

Currently gcc applies this to multiple components of a union type as well.
(At least with gcc 3.4 through 4.5 here.)

For instance, this program:

#include <stdio.h>

int main(int argc, char **argv) {
    union {
	struct { int i; char c[4]; } a; 
	struct { int i; short s[2]; } b;
    } u = { .a.i = 1, .b.s[0] = 2, .b.s[1] = 3 };

    printf("%d %d %d\n", u.a.i, u.b.s[0], u.b.s[1]);
}

will print "0 2 3" when compiled with gcc, since gcc appears to treat
this as two initializations of the "same field" (fields mapped to the
same spot in memory):

     u.a = { 1 };
     u.b = { 0, 2, 3};

and discards the first.    (By comparison, the Solaris Studio compiler
prints "1 2 3" for this code.)

If the current behavior of gcc is considered correct, then it would be helpful 
to update the documentation to say something like:

   If the same field is initialized multiple times, or overlapping members
   of the same union are initialized, the value from the last initialization
   will be used.

   When union members are structures, the entire structure from the last
   member initialized is used.   For example:

    union {
	struct { int i; char c[4]; } a; 
	struct { int i; short s[2]; } b;
    } u = { .a.i = 1, .b.s[0] = 2, .b.s[1] = 3 };

   is equivalent to:

   union {
	struct { int i; char c[4]; } a; 
	struct { int i; short s[2]; } b;
    } u = { .a = { 1 }, .b = { 0, 2, 3 } };

   which is in turn equivalent to:

   union {
	struct { int i; char c[4]; } a; 
	struct { int i; short s[2]; } b;
    } u = { .b = { 0, 2, 3 } };
Comment 1 sandra 2018-11-23 05:18:51 UTC
Author: sandra
Date: Fri Nov 23 05:18:19 2018
New Revision: 266402

URL: https://gcc.gnu.org/viewcvs?rev=266402&root=gcc&view=rev
Log:
2018-11-22  Sandra Loosemore  <sandra@codesourcery.com>
	    Alan Coopersmith  <alan.coopersmith@oracle.com>

	PR c/53608

	gcc/
	* doc/extend.texi (Designated Inits): Clarify handling of multiple
	initializers for unions.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/doc/extend.texi
Comment 2 sandra 2018-11-23 05:40:56 UTC
Fixed on trunk. 

I filed PR 88144 and PR 88158 for some other problems I noted in the manual section on designated initializers.