In unions the initialization is done to the first member only.but is there any specific reason why we cannot initialize other members in the same fashion as first member?
In unions the initialization is done to the first member only.but is there any specific reason why we cannot initialize other members in the same fashion as first member?
In C99 you can use designated initializer
In C89 (notably Microsoft's Visual Studio is still using this version of C), I think, only the first member of a union can be initialized. But do not rely on unions. You should avoid them in the first place.Code:#include <stdio.h> union foo { double x; int n; }; int main(void) { union foo bar = { .n = 42 }; printf("the member n has value %d\n", bar.n); }
Last edited by qny; 11-19-2012 at 01:56 PM.
@Saurabh Mehta
Where'd you get that info? It seems to be wrong or outdated:
Originally Posted by C99 section 6.7.8 paragraph 38
Since all members in a union share the same memory, any initialization constant applies to all elements equally. Essentially there is only one element which has multiple names.
Not sure that's correct. Take for example:
.c and .d don't share exactly the same memory. initializing .c may only initialize one byte of the 8 used by the double, you aren't initializing .d to 120.Code:union { char c; double d; } u = { .c = 'x' }; // set .c to 'x', a decimal value of 120 in ASCII
Code:$ cat bar.c #include <stdio.h> #include <string.h> int main(void) { union { char c; double d; } u = { .c = 'x' }; // set .c to 'x', a decimal value of 120 in ASCII printf("u.c = '%c', decimal value %hhd\n", u.c, u.c); printf("u.d = %.30f, hex representation 0x%016llx\n", u.d, *((unsigned long long *) &u.d)); return 0; } $ make bar gcc -Wall -Werror -ggdb3 -std=c99 -pedantic bar.c -o bar -lm -lpthread -lefence $ ./bar u.c = 'x', decimal value 120 u.d = 0.000000000000000000000000000000, hex representation 0x0000000000000078
I've never seen an initializer such as this before:;Code:... = { .c = 'x' }
I use designated initializers all the time when I need to call a POSIX system call that takes a pointer to a structure (POSIX requires that structures include at least certain members, but it does not restrict implementations from including more members, nor does it specify the order of members).
Code:/* set an interval timer to run every 1.5 seconds */ struct tv = { .it_interval = { .tv_sec = 1, .tv_usec = 500000, }, .it_value = { .tv_sec = 1, .tv_usec = 500000, }, }; #if 0 /* alternative method without designated initializers */ struct tv; memset(tv, 0, sizeof tv); tv.it_interval.tv_sec = 1; tv.it_interval.tv_usec = 500000; tv.it_value.tv_sec = 1; tv.it_value.tv_usec = 500000; #endif setitimer(ITIMER_REAL, &tv, NULL);
@qnyI know that by using '.' operator we can initialize the other members but my question was that "is there a reason for why initialization without '.' operator implies initialization of first member only"?
From the C99 rationale, section 6.7.8 (p89, lines 16-19):
So it looks like that was a convention used by some compilers back before the first C standard (C89). It makes sense, since any union type specifier will have at least one member*, the first one. A union type specifier with only one member is perfectly valid C, even if it is a bit silly. Besides, how would it work? I mean, how would the compiler know to initialize the nth element instead of the 1st? You would need something equivalent to the . operator in the initializer, but specified by a number instead of a name. But if the union elements were ever reordered (perhaps for alignment reasons), your initializations would need fixing too. So just initialize the element you want by field name.The C89 Committee adopted the rule (already used successfully in some implementations) that
the first member of the union is the candidate for initialization. Other notations for union
initialization were considered, but none seemed of sufficient merit to outweigh the lack of prior
art, until C99.
* Technically, a union (or struct) can have zero elements in it's type specifier, but that results in undefined behavior, so it's not worth much consideration.
@anduril462 you mean to sayis valid that is union declaration without any membors is valid?Code:union a{}aa;
Yes, that is what anduril is saying.