Thread: Unions.

  1. #1
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357

    Unions.

    Hello to all. We say that a union is a way to save some space in structures. I have a question... assuming that we have the following union :

    Code:
    union {
    	int i;
    	double d;
    } u;
    if the union store an integer and not a double.... what happens with the remaining space?

    Another question if I have

    Code:
    typedef union {
    	int i;
    	double d;
    } Number ;
    
    int main( void )
    {
    	Number array_numbers[10];
    	
            return 0;
    }
    So array_numbers is an array of unions? We can say that is an array of unions? because it has a similar way with arrays of structures to access an element arrays subscript + (.) operator + name of the member also a union each time it stores only one (integer or double) :

    Code:
    array_numbers[0].i = 1;
    array_numbers[1].d = 1.5;  // and so forth....
    Thank you in advance.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    You know, I feel you are starting to lean on this forum too much.

    You'll learn more if you experiment and search for answers of your own.

    So, for example, throw several `union' and `sizeof' statements at your compiler with relevant `printf' statements so that you may try and draw conclusions about "the remaining space" for yourself, and once you have some ideas, you can ask here for confirmation or other support.

    Sure, you can always ask here if your conclusions are correct, but you really are doing yourself a disservice simply reaching towards this forum for every little question.

    Just to be clear, I'm not recommending you reach for a search engine either by default.

    Soma

  3. #3
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Mr.Lnx View Post
    ...
    if the union store an integer and not a double.... what happens with the remaining space?
    It takes unspecified values. Assuming an int occupies 4 bytes and a double 8 bytes, then when you assign a value to u.i it fills up the 4 corresponding bytes (leading or trailing, depending on the endianess) while the remaining 4 bytes take unspecified values.

    Another question if I have
    ...
    So array_numbers is an array of unions? We can say that is an array of unions? because it has a similar way with arrays of structures to access an element arrays subscript + (.) operator + name of the member also a union each time it stores only one (integer or double) :
    Yes, I guess you could say that (you have an array of unions).

    PS. From what I remember by heart, according to ANSI C89/ISO 90 we can only assign values to the 1st member of a union, but I think this may have changed in later versions of the standard (C99? C11?). I'm not sure, but I'm too lazy right now to check with the standard :P

  4. #4
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by migf1 View Post
    PS. From what I remember by heart, according to ANSI C89/ISO 90 we can only assign values to the 1st member of a union, but I think this may have changed in later versions of the standard (C99? C11?). I'm not sure, but I'm too lazy right now to check with the standard :P
    Yes of course it has changed. Do not forget Designated Initiliazers as a special C99 feature

    C99 Designated Initializers is my favourite feature too.
    Last edited by Mr.Lnx; 06-11-2013 at 11:07 AM.

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    We say that a union is a way to save some space in structures
    Not really... union has to be the right semantics. When you store something in the union, the value becomes that thing. Whereas with a structure, you can maintain several values at once which obviously requires more space.

  6. #6
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Quote Originally Posted by Mr.Lnx View Post
    Yes of course it has changed. Do not forget Designated Initiliazers as a special C99 feature

    C99 Designated Initializers is my favourite feature too.
    You are right, it's about brace-initialization and not about assignment (I was remembering wrong). I just had a look at both the C90 and the C99 drafts of the standard...

    Quote Originally Posted by "C89/90 - 6.5.7 Initialization
    A brace-enclosed initializer for a union object initializes the member that appears first in the declaration list of the union type.
    * in C99 it's under 6.7.8 17 with different wording.

    So there's no problem in directly assigning a value to any member of the union. However, it is considered unspecified behavior to use the value of a union member other than the last one we used for storing the value (C99 : Annex J.1 - Portability Issues/Unspecified Behavior).

  7. #7
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Sorry again but I have some other questions (If it is worth please respond to me...)

    Code:
    struct catalog_item {
    	int stock_number;
    	int price;
    	int item_type;
    	union {
    		struct {
    	 		char title[TITLE_LEN+1];
    			char author[AUTHOR_LEN + 1];
    			int num_pages;
    		}book;
    		struct {
    			char design[DESIGN_LEN+1];
    		}mug;
    		struct {
    			char design[DESIGN_LEN + 1];
    			int colors;
    			int sizes;
    		}shirt;
    	} item;  
    	
    };
    However the C standard mentions a special case : two or more of the members of the union are structures and the structures begin with one or more matching members.(These members need to be in the same order and have compatible types , but need not have the same name.) If one of the structures is currently valid , then the matching members in other structures will be also valid.Consider the union embedded in the catalog_item structure.It contains three structures as members two of which (mug and shirt) begin with a matching member (design).Now suppose that we assign a value to one of the design members:

    strcpy( c.item.mug.design , "Cats"); The design member in the other structure will be defined and have the same value :

    printf(" %s " , c.item.shirt.design );


    What does it mean with the "compatible types of members?" same length(DESIGN_LEN+1) and type(char)?

    Second one is that C standard specifies that holes are allowed only between members or after the last member.One consequence is that a pointer to the first member of a structure is guaranteed to be the same as a pointer to the entire structure (Note however that the two pointers won't have the same type).

    Is there any better explanation of that? I can't understand sorry

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by Mr.Lnx View Post
    A union is a way to save some space in structures.
    It mostly provides a way to look at the same variable in two different ways. For this example, assuming long long means a 64 bit integer, then you can look at that 64 bit variable as 64 bit integer or as a double precision value:

    Code:
    union {
        long long i;
        double d;
    } u;
    Quote Originally Posted by Mr.Lnx View Post
    ... What does it mean with the "compatible types of members?"
    Those members need to be of the same size and type. If the types are not the same, you need to make sure that the members have the same offset within a structure, and the offset can be affected by padding to boundaries, such as placing a 32 bit pointer on a 4 byte boundary. The include file "stddef.h", defines a macro for finding the offset of member "m" within structure "s". Note, size_t is an unsigned integer, 32 bits in a 32 bit environment and 64 bits in a 64 bit environment (at least for microsoft compilers):

    Code:
    #define offsetof(s,m)    (size_t)&(((s *)0)->m)
    Last edited by rcgldr; 06-11-2013 at 04:39 PM.

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Note, size_t is an unsigned int, 32 bits in a 32 bit environment and 64 bits in a 64 bit environment.
    O_o

    That's not correct. The size of types depends on the compiler.

    Soma

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    Quote Originally Posted by phantomotap View Post
    O_o

    That's not correct. The size of types depends on the compiler.

    Soma
    here is a good explanation of differing data type sizes for 64 bit platforms.
    64-bit computing - Wikipedia, the free encyclopedia

  11. #11
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by rcgldr View Post
    Note, size_t is an unsigned integer, 32 bits in a 32 bit environment and 64 bits in a 64 bit environment (at least for microsoft compilers) ...
    Quote Originally Posted by phantomotap View Post
    That's not correct. The size of types depends on the compiler.
    Which is why I specifically mentioned microsoft compilers. The generic definition for size_t is that it has to be an unsigned integer large enough to represent the size of the maximum size object for a particular environment. In the case of microsoft compilers, size_t is either 32 bits or 64 bits.
    Last edited by rcgldr; 06-11-2013 at 04:39 PM.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Which is why I specifically mentioned microsoft compilers. The generic definition for size_t is that it has to be large enough to represent the size of the maximum size object for a particular environment. In the case of microsoft compilers, size_t is either 32 bits or 64 bits.
    O_o

    That's all fine and dandy, but I was actually referencing your use of "unsigned int".

    Of course, you may have simply intended "unsigned integer type" rather than "unsigned int" specifically.

    Soma

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by phantomotap View Post
    I was actually referencing your use of "unsigned int".
    I corrected my previous posts to use the generic term unsigned integer.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I corrected my previous posts to use the generic term unsigned integer.
    O_o

    I see.

    Thank you for rephrasing to eliminate the confusion.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unions
    By Saurabh Mehta in forum C Programming
    Replies: 7
    Last Post: 04-05-2013, 12:13 PM
  2. unions
    By jduke44 in forum C Programming
    Replies: 2
    Last Post: 10-26-2005, 03:50 PM
  3. unions
    By mickle in forum C Programming
    Replies: 6
    Last Post: 02-27-2003, 11:46 PM
  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