Thread: Unions in C

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    50

    Unions in C

    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?

  2. #2
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    In C99 you can use designated initializer

    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);
    }
    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.
    Last edited by qny; 11-19-2012 at 01:56 PM.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    @Saurabh Mehta
    Where'd you get that info? It seems to be wrong or outdated:
    Quote Originally Posted by C99 section 6.7.8 paragraph 38
    EXAMPLE 13 Any member of a union can be initialized:
    Code:
    union { /*... */ } u = { .any_member = 42 };

  4. #4
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    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.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by nonoob View Post
    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:
    Code:
    union {
        char c;
        double d;
    } u = { .c = 'x' };  // set .c to 'x', a decimal value of 120 in ASCII
    .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:
    $ 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

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I've never seen an initializer such as this before:
    Code:
    ... = { .c = 'x' }
    ;

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    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);

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    50
    @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"?

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    From the C99 rationale, section 6.7.8 (p89, lines 16-19):
    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.
    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.

    * 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.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by anduril462 View Post
    * 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.
    I assume you mean that (non-default) initialisation of such a union or struct will give undefined behaviour. There is nothing wrong with creating such a union or struct (although the ways of using it are fairly limited, naturally).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User
    Join Date
    Nov 2012
    Posts
    50
    @anduril462 you mean to say
    Code:
    union a{}aa;
    is valid that is union declaration without any membors is valid?

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Yes, that is what anduril is saying.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by grumpy View Post
    I assume you mean that (non-default) initialisation of such a union or struct will give undefined behaviour. There is nothing wrong with creating such a union or struct (although the ways of using it are fairly limited, naturally).
    No, I think I meant what I said, except I forgot the "named" part. Of course, if I mis-interpreted the standard, it wouldn't be the first time.
    Quote Originally Posted by C99 6.7.2.1p7
    The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type,
    within a translation unit. The struct-declaration-list is a sequence of declarations for the
    members of the structure or union. If the struct-declaration-list contains no named
    members, the behavior is undefined. The type is incomplete until after the}that
    terminates the list.
    Emphasis mine.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using Unions
    By deciel in forum C Programming
    Replies: 1
    Last Post: 01-31-2012, 11:46 PM
  2. unions
    By jduke44 in forum C Programming
    Replies: 2
    Last Post: 10-26-2005, 03:50 PM
  3. Unions?
    By Sure in forum C Programming
    Replies: 8
    Last Post: 06-30-2005, 02:47 AM
  4. Unions in c++
    By The Gweech in forum C++ Programming
    Replies: 5
    Last Post: 08-06-2002, 08:14 AM
  5. Unions?
    By hostensteffa in forum C++ Programming
    Replies: 3
    Last Post: 06-08-2002, 06:01 AM