From this question one could start to believe that alignment of a union is not less than the largest alignment of it's individual members. But I have a problem with the long long
type in gcc/g++. The full example can be found here, but here are the relevant parts for my question:
union ull {
long long m;
};
struct sll {
long long m;
};
int main() {
#define pr(v) cout << #v ": " << (v) << endl
pr(sizeof(long long));
pr(__alignof__(long long));
pr(sizeof(ull));
pr(__alignof__(ull));
pr(sizeof(sll));
pr(__alignof__(sll));
};
This results in the following output:
sizeof(long long): 8
__alignof__(long long): 8
sizeof(ull): 8
__alignof__(ull): 4
sizeof(sll): 8
__alignof__(sll): 4
Why is the alignment of a union member bigger than that of the containing union?
[UPDATE]
According to Keith's answer alignof is wrong here. But I test the following and it seems that alignof tells us the true. See:
union ull {
long long m;
};
long long a;
char b;
long long c;
char d;
ull e;
int main() {
#define pr(v) cout << #v ": " << (v) << endl
pr(size_t((void*)&b));
pr(size_t((void*)&c));
pr(size_t((void*)&d));
pr(size_t((void*)&e));
pr(size_t((void*)&c) - size_t((void*)&b));
pr(size_t((void*)&e) - size_t((void*)&d));
};
The output:
size_t((void*)&b): 134523840
size_t((void*)&c): 134523848
size_t((void*)&d): 134523856
size_t((void*)&e): 134523860
size_t((void*)&c) - size_t((void*)&b): 8
size_t((void*)&e) - size_t((void*)&d): 4
So, the alignment of long long
is 8 and alignment of union containing long long
is 4 in global data. For local scope I cannot test this since it seems that compiler is free to rearrange local data - so this trick does not work. Can you comment on this?
[/UPDATE]
__alignof__
(which is a gcc extension) doesn't necessarily report the required alignment for a type.x86 processors, for example don't really require more than 1-byte alignment for any type. Access to a 4-byte or 8-byte object will likely be more efficient if the object is word-aligned, but byte alignment is sufficient.
Quoting the gcc documentation:
But that still doesn't really answer the question. Even with that loose definition, I can't think of any good reason for
__alignof__
to indicate a stricter alignment forlong long
than for a struct or union containing along long
.A more portable method of determining the alignment of a type is this:
This yields the offset of a member of type
t
in a struct consisting of achar
and at
. Using this macro, this program:produces this output on my system (gcc-4.7, Ubuntu 12.04, x86):
The results indicated by my
ALIGNOF()
macro are consistent:long long
has 4-byte alignment, and a struct or union containing along long
has 4-byte alignment.I suspect this is a bug, or at least an inconsistency, in gcc's implementation of
__alignof__
. But the vagueness of the definition makes it hard to be certain that it's really a bug. It doesn't seem to have been reported.Update :
I may be jumping the gun, but I've just submitted a bug report.
This earlier bug report, closed as "INVALID", is similar, but it doesn't refer to the alignment of the structure itself.
Update 2 :
My bug report has been closed as a duplicate of the earlier one. I'll be asking for clarification.