Silent change in boost 1.36 alignment_of<> template with gcc 4.3

In boost 1.36, boost::alignment_of<> was changed to use the builtin __alignof__() if gcc version was 4.3 or greater rather than using calculating alignement using: template <typename T> struct alignment_of_hack { char c; T t; alignment_of_hack(); }; Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures. What do people think about adding a struct_alignment_of<> template that uses the old logic to compute alignment inside a struct? -- Jon Biggar jon@floorboard.com jon@biggar.org jonbiggar@gmail.com

Jon Biggar wrote:
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
I personally never understood why gcc's alignof returns that. It doesn't even make sense, since the size of double is not a multiple of 8, so multiple doubles right after each other can't possibly be 8-byte aligned.

on Sat Nov 08 2008, Mathias Gaunard <mathias.gaunard-AT-ens-lyon.org> wrote:
Jon Biggar wrote:
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
I personally never understood why gcc's alignof returns that. It doesn't even make sense, since the size of double is not a multiple of 8, so multiple doubles right after each other can't possibly be 8-byte aligned.
We could easily either specialize our way around it or limit the result of alignment_of<T> to sizeof(T). The latter seems like a smart thing to do anyway. Thoughts? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

AMDG David Abrahams wrote:
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
We could easily either specialize our way around it or limit the result of alignment_of<T> to sizeof(T). The latter seems like a smart thing to do anyway.
sizeof(double) is usually 8 isn't it? In Christ, Steven Watanabe

Steven Watanabe wrote:
sizeof(double) is usually 8 isn't it?
Argh, my bad, I thought we were talking about floats and mixed issues... There is no real issue with alignment_of<double>::value being 8 then, even if it's not the default alignment.

David Abrahams wrote:
on Sat Nov 08 2008, Mathias Gaunard <mathias.gaunard-AT-ens-lyon.org> wrote:
Jon Biggar wrote:
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures. I personally never understood why gcc's alignof returns that. It doesn't even make sense, since the size of double is not a multiple of 8, so multiple doubles right after each other can't possibly be 8-byte aligned.
We could easily either specialize our way around it or limit the result of alignment_of<T> to sizeof(T). The latter seems like a smart thing to do anyway.
Thoughts?
I'm becoming convinced that we just shouldn't us the __alignof__() builtin from gcc because it lies. -- Jon Biggar jon@floorboard.com jon@biggar.org jonbiggar@gmail.com

On Sun, Nov 9, 2008 at 7:42 AM, Jon Biggar <jon@biggar.org> wrote:
David Abrahams wrote:
on Sat Nov 08 2008, Mathias Gaunard <mathias.gaunard-AT-ens-lyon.org> wrote:
Jon Biggar wrote:
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
I personally never understood why gcc's alignof returns that. It doesn't even make sense, since the size of double is not a multiple of 8, so multiple doubles right after each other can't possibly be 8-byte aligned.
We could easily either specialize our way around it or limit the result of alignment_of<T> to sizeof(T). The latter seems like a smart thing to do anyway.
Thoughts?
I'm becoming convinced that we just shouldn't us the __alignof__() builtin from gcc because it lies.
I wouldn't say it likes; from gcc __alignof__ docs: " Some machines never actually require alignment; they allow reference to any data type even at an odd address. For these machines, `__alignof__' reports the _recommended_ alignment of a type." x86 is one of those machines (no alignment ever required except for some XMM instructions). The recommended alignment for double is 8 bytes, even if the ABI, for historical reason only requires 4. -- gpd

Giovanni Piero Deretta wrote:
I'm becoming convinced that we just shouldn't us the __alignof__() builtin from gcc because it lies.
I wouldn't say it likes; from gcc __alignof__ docs:
" Some machines never actually require alignment; they allow reference to any data type even at an odd address. For these machines, `__alignof__' reports the _recommended_ alignment of a type."
x86 is one of those machines (no alignment ever required except for some XMM instructions). The recommended alignment for double is 8 bytes, even if the ABI, for historical reason only requires 4.
I say it lies because the result is useless for structure alignment calculations. -- Jon Biggar jon@biggar.org jon@floorboard.com

Jon Biggar wrote:
In boost 1.36, boost::alignment_of<> was changed to use the builtin __alignof__() if gcc version was 4.3 or greater rather than using calculating alignement using:
template <typename T> struct alignment_of_hack { char c; T t; alignment_of_hack(); };
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
Hmmm, do you have a test case? I ask because the type_traits tests compare the result of alignment_of<>::value with the actual alignment inside a struct... and the tests are all passing. Thanks, John.

John Maddock wrote:
In boost 1.36, boost::alignment_of<> was changed to use the builtin __alignof__() if gcc version was 4.3 or greater rather than using calculating alignement using:
template <typename T> struct alignment_of_hack { char c; T t; alignment_of_hack(); };
Unfortunately, this broke some code I had written that did structure introspection, because gcc's __alignof__() returns 8 for double on the x86 architecture, but actually only aligns doubles on 4 byte boundaries inside structures.
Hmmm, do you have a test case?
I ask because the type_traits tests compare the result of alignment_of<>::value with the actual alignment inside a struct... and the tests are all passing.
This is what the alignment_of test case outputs on my system: alignment_of_test.cpp:78: The expression: "::boost::alignment_of<double>::value" had an invalid value (found 8, expected 4) alignment_of_test.cpp:81: The expression: "::boost::alignment_of< ::boost::long_ long_type>::value" had an invalid value (found 8, expected 4) That's with this version of gcc from Fedora 9: gcc version 4.3.0 20080428 (Red Hat 4.3.0-8) (GCC) -- Jon Biggar jon@floorboard.com jon@biggar.org jonbiggar@gmail.com

Jon Biggar wrote:
This is what the alignment_of test case outputs on my system:
alignment_of_test.cpp:78: The expression: "::boost::alignment_of<double>::value" had an invalid value (found 8, expected 4) alignment_of_test.cpp:81: The expression: "::boost::alignment_of<
boost::long_ long_type>::value" had an invalid value (found 8, expected 4)
That's with this version of gcc from Fedora 9:
gcc version 4.3.0 20080428 (Red Hat 4.3.0-8) (GCC)
OK I've reproduced that on an i386 Linux system: looks like all our tests are run on x64 boxes where the test does pass. Are you on a 32-bit Linux box? Thanks, John.

John Maddock wrote:
Jon Biggar wrote:
This is what the alignment_of test case outputs on my system:
alignment_of_test.cpp:78: The expression: "::boost::alignment_of<double>::value" had an invalid value (found 8, expected 4) alignment_of_test.cpp:81: The expression: "::boost::alignment_of<
boost::long_ long_type>::value" had an invalid value (found 8, expected 4)
That's with this version of gcc from Fedora 9:
gcc version 4.3.0 20080428 (Red Hat 4.3.0-8) (GCC)
OK I've reproduced that on an i386 Linux system: looks like all our tests are run on x64 boxes where the test does pass. Are you on a 32-bit Linux box?
Yes. -- Jon Biggar jon@biggar.org jon@floorboard.com

Jon Biggar wrote:
OK I've reproduced that on an i386 Linux system: looks like all our tests are run on x64 boxes where the test does pass. Are you on a 32-bit Linux box?
Yes.
OK I've disabled use of __alignof__ in Trunk for all 32-bit Unix platforms. John.
participants (6)
-
David Abrahams
-
Giovanni Piero Deretta
-
John Maddock
-
Jon Biggar
-
Mathias Gaunard
-
Steven Watanabe