458,134 Members | 1,265 Online Need help? Post your question and get tips & solutions from a community of 458,134 IT Pros & Developers. It's quick & easy.

# sizeof a union

 P: n/a My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Thanks in advance. -- Regards. Mockey Chen Email: mo*********@gmail.com Nov 29 '05 #1
18 Replies

 P: n/a Mockey Chen wrote: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Short answer: Why not? Somewhat longer answer: Maybe shorts are 4 bytes wide on your machine... Or maybe there's alignment... Or... ... ... Nov 29 '05 #2

 P: n/a Sven Hesse wrote: Mockey Chen wrote: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Short answer: Why not? Somewhat longer answer: Maybe shorts are 4 bytes wide on your machine... Or maybe there's alignment... Or... ... ... The size of the structure struct y is 6 bytes.The size of short is 2 bytes.There are 3 variables in the structure.each character also has a size of two bytes. hence 3*2 bytes= 6 bytes Nov 29 '05 #3

 P: n/a robotnik wrote: each character also has a size of two bytes. ....Err, since when is a char 2 bytes wide? If I'm not totally mistaken, a char has _always_ a size of 1 byte... Nov 29 '05 #4

 P: n/a Mockey Chen wrote: My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. The size of a union is the size of its largest member; in this case, that would be struct y. The most likely reason that the struct is 6 bytes long instead of 5 is due to alignment restrictions; many architectures require multibyte objects to start on mod 2 or mod 4 addresses, so there's probably an unused byte between the struct members a and b. For fun, try rearranging the contents of struct y and see if you get a different result. Thanks in advance. -- Regards. Mockey Chen Email: mo*********@gmail.com Nov 29 '05 #5

 P: n/a Sven Hesse wrote: robotnik wrote: each character also has a size of two bytes. ...Err, since when is a char 2 bytes wide? If I'm not totally mistaken, a char has _always_ a size of 1 byte... Size of char is _at least_ 1 byte. -- C faq: http://www.eskimo.com/~scs/C-faq/top.html Reference: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/ Coding standards: http://www.psgd.org/paul/docs/cstyle/cstyle.htm Nov 29 '05 #6

 P: n/a Tatu Portin wrote: Size of char is _at least_ 1 byte. Quote out of the C FAQ found in your sig (question 7.8): "It's never necessary to multiply by sizeof(char), since sizeof(char) is, by definition, exactly 1." ? Nov 29 '05 #7

 P: n/a Tatu Portin: Sven Hesse: robotnik: each character also has a size of two bytes. ...Err, since when is a char 2 bytes wide? If I'm not totally mistaken, a char has _always_ a size of 1 byte... Size of char is _at least_ 1 byte. No! 6.5.3.4 The sizeof operator 2 The sizeof operator yields the size (in bytes) of its operand, ... 3 When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. Jirka Nov 29 '05 #8

 P: n/a Tatu Portin said: Sven Hesse wrote: robotnik wrote: each character also has a size of two bytes. ...Err, since when is a char 2 bytes wide? If I'm not totally mistaken, a char has _always_ a size of 1 byte... Size of char is _at least_ 1 byte. True. It is also at most 1 byte. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at above domain (but drop the www, obviously) Nov 29 '05 #9

 P: n/a Tatu Portin wrote: Size of char is _at least_ 1 byte. This seems a perverse thing for you to have posted. Why did you not include the equally true statement that sizeof(char) is _at most_ 1 byte? Nov 29 '05 #10

 P: n/a On Tue, 29 Nov 2005 23:10:34 +0800, in comp.lang.c , "Mockey Chen" wrote: My friend ask me a question as following: of the size of a union or struct My compiler tell me the answer is 6.I want to know why the answer is 6. This is a FAQ. -- Mark McIntyre CLC FAQ CLC readme: ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==---- http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups ----= East and West-Coast Server Farms - Total Privacy via Encryption =---- Nov 29 '05 #11

 P: n/a "Mockey Chen" wrote in message news:dm**********@news.yaako.com... My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Why not add another member and use that to 'explore' the other members, e.g.,: #include typedef union { int x; struct { int a; int b; char c; } y; struct { unsigned char a; unsigned char b; unsigned char c; unsigned char d; unsigned char e; unsigned char f; } z; }SU; int main(void) { SU a; printf("x = \t%p\n", &a.x); printf("y.a = \t%p\n", &a.y.a); printf("y.b = \t%p\n", &a.y.b); printf("y.c = \t%p\n", &a.y.c); printf("z.a = \t%p\n", &a.z.a); printf("z.b = \t%p\n", &a.z.b); printf("z.c = \t%p\n", &a.z.c); printf("z.d = \t%p\n", &a.z.d); printf("z.e = \t%p\n", &a.z.e); printf("z.f = \t%p\n", &a.z.f); return 0; } Nov 29 '05 #12

 P: n/a On 2005-11-29, pemo wrote: "Mockey Chen" wrote in message news:dm**********@news.yaako.com... My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Why not add another member and use that to 'explore' the other members, e.g.,: [snipped] Out of curiosity, why is it impossible to add a 'flexible array' to a union? The best solution to this IMO would be an "unsigned char data[];" member. Nov 29 '05 #13

 P: n/a Jordan Abel wrote: On 2005-11-29, pemo wrote: "Mockey Chen" wrote in message news:dm**********@news.yaako.com... My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. Why not add another member and use that to 'explore' the other members, e.g.,: [snipped] Out of curiosity, why is it impossible to add a 'flexible array' to a union? The best solution to this IMO would be an "unsigned char data[];" member. Because that's pointless. If you want that, cast the address of the thing to an unsigned char* and use that. Overloading flexible arrays for that isn't worth it. S. Nov 29 '05 #14

 P: n/a pemo wrote: typedef union { int x; struct { int a; int b; int main(void) { SU a; printf("x = \t%p\n", &a.x); If using %p you should cast the pointer to void* printf("x = \t%p\n", (void*)&a.x); printf("y.a = \t%p\n", &a.y.a); Also, for this sort of thing using the offsetof macro from stddef.h would be more useful. -- Flash Gordon Living in interesting times. Although my email address says spam, it is real and I read it. Nov 29 '05 #15

 P: n/a "Mockey Chen" writes: My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? Please post real code. The union appears at first glance to have two members, but you haven't actually declared the second member. You have a struct declaration (I don't think that's even legal in this context), but you haven't declared anything of that type. Assuming that's corrected ... sizeof(SU) is the number of bytes occupied by an object of type SU. My compiler tell me the answer is 6. I want to know why the answer is 6. It happens to be 6 in the particular implementation you're using. That's probably a very common result, but it's not required. Most likely the union has the same size as its largest member, which is the struct. It's certain that sizeof(char) is 1; it's likely that sizeof(short) is 2, and that shorts require 2-byte alignment. Within the struct, that puts "char a" at offset 0, "short b" at offset 2 (with a 1-byte gap for alignment), and "char c" at offset 4. An additional 1-byte gap appears at the end of the structure so that the b member within elements of an array of structures will be properly aligned. This makes for a total of 6 bytes. But the compiler is free to insert padding anywhere it likes (other than at the beginning), and type short needn't necessarily be 2 bytes; it could be 1 byte if CHAR_BIT is at least 16, and I've worked on systems where sizeof(short)==8. Even assuming sizeof(short)==2, the compiler might find it convenient to pad the structure (and therefore the union) to 8 bytes and require 4-byte alignment. Some more comments: Don't use identifiers starting with an underscore. Some are reserved to the implementation. The rule is more complicated than that, depending on what follows the underscore, but the safest rule is to avoid such identifiers altogether. Using a typedef for a union or structure really isn't particularly useful. Unless you're creating an abstract data type, where the code using it shouldn't know that it's a union or structure, it's easier just to use "struct foo" or "union bar". Your example could then be: union SU { short x; struct { char a; short b; char c; } y; }; (though all-caps identifiers are conventionally reserved for macro names). Note that the struct type is anonymous; that's ok, since it only appears as part of the union. Given union SU obj; you can then refer to obj.x obj.y.a obj.y.b obj.y.c -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 29 '05 #16

 P: n/a Keith Thompson wrote: "Mockey Chen" writes: My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? Please post real code. The union appears at first glance to have two members, but you haven't actually declared the second member. You have a struct declaration (I don't think that's even legal in this context), but you haven't declared anything of that type. Assuming that's corrected ... sizeof(SU) is the number of bytes occupied by an object of type SU. My compiler tell me the answer is 6. I want to know why the answer is 6. It happens to be 6 in the particular implementation you're using. That's probably a very common result, but it's not required. Most likely the union has the same size as its largest member, which is the struct. It's certain that sizeof(char) is 1; it's likely that sizeof(short) is 2, and that shorts require 2-byte alignment. Within the struct, that puts "char a" at offset 0, "short b" at offset 2 (with a 1-byte gap for alignment), and "char c" at offset 4. An additional 1-byte gap appears at the end of the structure so that the b member within elements of an array of structures will be properly aligned. This makes for a total of 6 bytes. But the compiler is free to insert padding anywhere it likes (other than at the beginning), and type short needn't necessarily be 2 bytes; it could be 1 byte if CHAR_BIT is at least 16, and I've worked on systems where sizeof(short)==8. Even assuming sizeof(short)==2, the compiler might find it convenient to pad the structure (and therefore the union) to 8 bytes and require 4-byte alignment. Some more comments: Don't use identifiers starting with an underscore. Some are reserved to the implementation. The rule is more complicated than that, depending on what follows the underscore, but the safest rule is to avoid such identifiers altogether. Using a typedef for a union or structure really isn't particularly useful. Unless you're creating an abstract data type, where the code using it shouldn't know that it's a union or structure, it's easier just to use "struct foo" or "union bar". Your example could then be: union SU { short x; struct { char a; short b; char c; } y; }; (though all-caps identifiers are conventionally reserved for macro names). Note that the struct type is anonymous; that's ok, since it only appears as part of the union. Given union SU obj; you can then refer to obj.x obj.y.a obj.y.b obj.y.c -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. See the following link http://www.eskimo.com/~scs/C-faq/q2.13.html Nov 29 '05 #17

 P: n/a "Robotnik" writes: Keith Thompson wrote: [snip] See the following link http://www.eskimo.com/~scs/C-faq/q2.13.html Yes, thank you, I should have mentioned that myself. But there was no need to quote my entire article (including the signature). -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 30 '05 #18

 P: n/a "John Bode" writes: Mockey Chen wrote: My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c; }; }SU; what is the sizeof (SU)? My compiler tell me the answer is 6. I want to know why the answer is 6. The size of a union is the size of its largest member; in this case, that would be struct y. Often is but it doesn't have to be. Alignment requirements for members, or alignment requirements imposed by the format of pointer-to-union, can cause the size of a union to be larger than the size of its largest member. Dec 3 '05 #19

### This discussion thread is closed

Replies have been disabled for this discussion. 