Thread: Size of the UNION

  1. #1
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78

    Question Size of the UNION

    Hello, as you know any element of the union starts with same address, and so.. the size of the union should be the size of the biggest element... right?
    but here what i have:

    Code:
         union myunion
         {
             short mem1;
             int mem2;
             double mem3;
             char str[10];
    
         };
    
    union myunion u1;
    now, when i do sizeof(u1) i get 12! but i should get 10, isnt it?

    interesting thing is, when i do it like that:
    Code:
         union myunion
         {
             short mem1;
             int mem2;
             double mem3;
             char str[12];
    
         };
    
    union myunion u1;
    and then perform again sizeof(u1), i get the correct size of 12!

    any ideas WHY?

    and here is the size of types on my system:
    short 2
    int 4
    double 8
    char 1

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    It depends on the implementation - on your system the most restrictive alignment type maybe an int.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by BlackOps View Post
    now, when i do sizeof(u1) i get 12! but i should get 10, isnt it?
    The compiler adds padding to four byte "word" boundaries usually, which as itCbitC points out is the size of an int. This is because it is more efficient for the processor to work with word size chunks, so the slight waste of memory is worth the improvement in performance.

    Moral: always use sizeof() to refer to a datatype, never hardcode a number, since the individual compiler has obvious leeway here.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78
    ok, then how about this:

    Code:
    struct pixel
    {
        unsigned short red : 8;
        unsigned short green : 8;
        unsigned short blue : 8;
    
        unsigned short val1 : 8;
        unsigned short val2 : 8;
    };
    
    struct byte
    {
        char bt;
    };
    
    
    struct pixel point1;
    struct byte mybyte;
    the sizeof(point1) gave me 6, and sizeof(mybyte) gave me 1 !

    if restrictive is 2 or 4, the sizeof(mybyte) should give me 2 or 4 isnt it?

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    For unions each member is offset zero from the base, so the alignment must be appropriate for each of the member types in the union. I was leaning toward 16 bytes for the sizeof u1 since a double is 8 bytes.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by BlackOps View Post
    if restrictive is 2 or 4, the sizeof(mybyte) should give me 2 or 4 isnt it?
    I would imagine if a struct contains only a single datatype the compiler simply uses that. Try "char bt[2]" and see what happens.

    There are no "rules" in the standard about this AFAIK altho you may be able to find a specific statement from the people responsible for your compiler. Also, it probably has an option or switch to disable padding if you have some strange reason for wanting to do that.

    I just said 4 byte word "usually" because I use gcc and it seems to me it does always use a multiple of 4 but YMMV.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78
    u mean u would have a result of 16 for sizeof(u1) on ur machine ?

  8. #8
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78
    ok here i go:
    Code:
    struct byte
    {
        char bt[2];
    };
    
    struct byte mybyte;
    now the sizeof(mybyte) gives me 2.

    by the way i am using the TCC compiler

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by BlackOps View Post
    ok, then how about this:

    Code:
    struct pixel
    {
        unsigned short red : 8;
        unsigned short green : 8;
        unsigned short blue : 8;
    
        unsigned short val1 : 8;
        unsigned short val2 : 8;
    };
    
    struct byte
    {
        char bt;
    };
    
    
    struct pixel point1;
    struct byte mybyte;
    the sizeof(point1) gave me 6, and sizeof(mybyte) gave me 1 !
    Bit fields are totally implementation-dependent so your best bet is the compiler manual that specifies how they are stored.
    Quote Originally Posted by BlackOps View Post
    if restrictive is 2 or 4, the sizeof(mybyte) should give me 2 or 4 isnt it?
    Restrictive in this context means when different types are grouped logically, like in a struct or union.
    In this case the most restrictive type would be a double because a char can begin on a byte boundary.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by BlackOps View Post
    u mean u would have a result of 16 for sizeof(u1) on ur machine ?
    yep!

  11. #11
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78
    well... then it looks clear now, thank you very much!

  12. #12
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by BlackOps View Post
    ok here i go:
    Code:
    struct byte
    {
        char bt[2];
    };
    
    struct byte mybyte;
    now the sizeof(mybyte) gives me 2.

    by the way i am using the TCC compiler
    The storage required for a type is different from its alignment requirements; bt[] needs 2 bytes of storage but it can be located anywhere as a char has no alignment requirements ie no padding is required for bt[] to tile a memory array.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by BlackOps View Post
    Code:
         union myunion
         {
             short mem1;
             int mem2;
             double mem3;
             char str[10];
    
         };
    
    union myunion u1;
    now, when i do sizeof(u1) i get 12! but i should get 10, isnt it?
    You might think the compiler is padding to ensure the alignment of the largest member. But the largest member is the double, which is 8 bytes, and 12 is not a multiple of 8. I'm not sure why the compiler is choosing 12.

    At any rate, the question is not useful because the alignment rules will differ on different platforms and then we're not talking about C anymore but a specific implementation of C with a specific compiler version on a specific platform. Your code will be more portable and less brittle if you never even ask these questions.

    interesting thing is, when i do it like that:
    Code:
         union myunion
         {
             short mem1;
             int mem2;
             double mem3;
             char str[12];
    
         };
    
    union myunion u1;
    and then perform again sizeof(u1), i get the correct size of 12!
    No. This is dangerous thinking. The compiler is ALWAYS correct. Regardless of what you think it ought to do. The number 12 is no more or less correct than the number 150. You're thinking too hard and it's going to bite you.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  14. #14
    Registered User BlackOps's Avatar
    Join Date
    Jul 2009
    Location
    AZERBAIJAN
    Posts
    78
    hmm... well ok, if its so much into implementation

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by brewbuck View Post
    No. This is dangerous thinking. The compiler is ALWAYS correct.
    Always? Not quite true - the standard is correct (at least, until it gets updated) and the standard is the basis on which correctness of a compiler is evaluated.

    However, in the case of something implementation defined, the standard grants the compiler has some freedom in what it implements within specified constraints. I suspect what you're trying to say is that any compiler that honours those constraints is then deemed correct.
    Quote Originally Posted by brewbuck View Post
    Regardless of what you think it ought to do. The number 12 is no more or less correct than the number 150. You're thinking too hard and it's going to bite you.
    To answer the original question, however, the size of any types is implementation defined (other than char types that have size one by definition) and - given specification of a union as being able to represent each of its members and them being in the same memory location - the size of a union is at least the size of its largest member.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Heapsort
    By xENGINEERx in forum C Programming
    Replies: 2
    Last Post: 03-30-2008, 07:17 PM
  2. Generic heapsort
    By Sephiroth1109 in forum C Programming
    Replies: 15
    Last Post: 12-07-2007, 06:14 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. An exercise in optimization
    By Prelude in forum Contests Board
    Replies: 10
    Last Post: 04-29-2005, 03:06 PM
  5. Using malloc() & qsort with a union
    By Cyber Kitten in forum C Programming
    Replies: 2
    Last Post: 09-02-2001, 07:57 AM