Mockey Chen said:
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