The __alignof__ operator applied to a struct type with a single long long member yields 4. This is inconsistent; a struct's alignment should be at least as large as the alignment of any of its members. I'm using gcc 4.7.0 on Ubuntu 12.04 x86. gcc -v says: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.7/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.0-7ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --disable-bootstrap --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.7.0 (Ubuntu/Linaro 4.7.0-7ubuntu3) Demo program (alignof_bug.c): ======================================== #include <stdio.h> #include <stddef.h> /* * See <http://stackoverflow.com/q/11825081/827263>, * posted by PiotrNycz */ /* * The ALIGNOF macro yields the alignment in bytes of a given type, * determined by how the compiler aligns a member of the type in * a struct following a single char member. */ #define ALIGNOF(type) ((int)(offsetof(struct {char c; type t;}, t))) struct wrapper { long long ll; }; int main(void) { printf("__alignof__(long long) = %d\n", (int)__alignof__(long long)); printf("__alignof__(struct wrapper) = %d\n", (int)__alignof__(struct wrapper)); printf("ALIGNOF(long long) = %d\n", (int)ALIGNOF(long long)); printf("ALIGNOF(struct wrapper) = %d\n", (int)ALIGNOF(struct wrapper)); if (__alignof__(long long) > __alignof__(struct wrapper)) { puts("Inconsistent __alignof__, long long vs. struct"); } if (__alignof__(long long) != ALIGNOF(long long)) { puts("Inconsistent alignment for long long"); } return 0; } ======================================== Output: ======================================== __alignof__(long long) = 8 __alignof__(struct wrapper) = 4 ALIGNOF(long long) = 4 ALIGNOF(struct wrapper) = 4 Inconsistent __alignof__, long long vs. struct Inconsistent alignment for long long ======================================== A response to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10360 suggests that __alignof__ needn't necessarily yield the same result as the offset of a member within a struct. I'm not sure I agree with that, but the main problem I'm reporting here refers to the alignment of the struct type itself, compared to the alignment of one of its members.
Forgot to mention: I compiled and executed the demo program as follows: gcc alignof_bug.c -o alignof_bug && ./alignof_bug
Because the ABI says so and __alignof__ does not return the minimum but the recommended alignment. Really a dup of 10360. *** This bug has been marked as a duplicate of bug 10360 ***
The results of the _Alignof operator (new in the 2011 ISO C standard) are the same as for the __alignof__ operator (not surprisingly). N1370 (C11 draft) 6.5.3.4 paragraph 3 says: The _Alignof operator yields the alignment requirement of its operand type. Richard Guenther: You say it's "Because the ABI says so". Do you have a reference to the ABI, particularly to a statement that a structure should have a smaller alignment than its member? You also say __alignof__ "does not return the minimum but the recommended alignment". That seems inconsistent with the use of the word "required" in C11. I just grabbed a copy of http://www.uclibc.org/docs/psABI-i386.pdf; is that the ABI you're referring to? Figure 3-1 covers alignment for scalar types. It says 8-byte floating-point has an alignment of 4 bytes, but it doesn't mention 8-byte integers. Furthermore, the following page says: Aggregates (structures and arrays) and unions assume the alignment of their most strictly aligned component. That seems inconsistent with the behavior of the following program: #include <stdio.h> int main(void) { printf("_Alignof(long long) = %d\n", (int)_Alignof(long long)); printf("_Alignof(struct {long long x;}) = %d\n", (int)_Alignof(struct {long long x;})); return 0; } whose output on my system, with gcc -std=c11 -pedantic c.c -o c && ./c is: _Alignof(long long) = 8 _Alignof(struct {long long x;}) = 4
My conclusion in bug 52023 was that _Alignof should differ from __alignof__ to meet the standard requirements (but really the standard didn't have such strange ABIs in mind at all).
(In reply to comment #3) > N1370 (C11 draft) 6.5.3.4 paragraph 3 says: > > The _Alignof operator yields the alignment requirement of its > operand type. Does that imply that an i386 host should return 1 for most types, simply because it *can* allow unaligned accesses?
On Wed, 8 Aug 2012, rth at gcc dot gnu.org wrote: > > N1370 (C11 draft) 6.5.3.4 paragraph 3 says: > > > > The _Alignof operator yields the alignment requirement of its > > operand type. > > Does that imply that an i386 host should return 1 for most types, > simply because it *can* allow unaligned accesses? Alignment requirements are defined in terms of "addresses at which objects of that type may be allocated", not in terms of what might happen with a pointer dereference.