Boost C++ Libraries: Ticket #1946: [type_traits] type_with_alignment fails on non-power-of-2 alignment https://svn.boost.org/trac10/ticket/1946 <p> The type_with_alignment template fails to compile if the alignment is not a power of 2. This is a possible situation at least with MSVC 9.0. The following class of a user-defined stream gets alignment of 12: </p> <p> class my_stream : </p> <blockquote> <p> public std::ostream </p> </blockquote> <p> { public: </p> <blockquote> <p> typedef boost::function0&lt; void &gt; function_type; function_type m_function; </p> </blockquote> <p> }; </p> <p> I've attached a reduced code sample with more comments and the compiler error message. </p> <p> I suggest to add a fallback type_with_alignment type in case if the alignment is not a power of 2. This type should have the requested alignment. It may be achieved with the <span class="underline">declspec(align(n)) specifier. </span></p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/1946 Trac 1.4.3 andysem@… Sat, 24 May 2008 15:23:59 GMT attachment set https://svn.boost.org/trac10/ticket/1946 https://svn.boost.org/trac10/ticket/1946 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">tt_failure.cpp</span> </li> </ul> <p> The sample code that reproduces the problem </p> Ticket John Maddock Mon, 02 Jun 2008 16:08:34 GMT status changed https://svn.boost.org/trac10/ticket/1946#comment:1 https://svn.boost.org/trac10/ticket/1946#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> This is really strange and appears to be an MSVC bug: </p> <p> The true alignment of the type as reported by alignof is 8, but The size of the type as reported by sizeof is 44, so... </p> <p> If you declare an array of my_class then some of the objects will *not* be 8-byte aligned, because the objects size is not a multiple of it's alignment! </p> <p> Even stranger, when my_class is placed in boost::detail::alignment_of_hack (the class we use to calculate the alignment), then it is placed on a 8-byte alignment, and alignment_of_hack gets given some trailing padding to pack out the class to a multiple of 8 (it needs this because sizeof(my_class) isn't a multiple of 8). </p> <p> So sometimes MSVC does the wrong thing, and sometimes it corrects itself, either way it really confuses our internal logic. </p> <p> I'm not really sure what to do here, except perhaps to start using the <span class="underline">align_of intrinsic... I'll look into that. </span></p> <p> Regards, John. </p> <p> PS I used the code below to deduce the above: </p> <p> #include &lt;boost/function.hpp&gt; #include &lt;boost/type_traits/alignment_of.hpp&gt; #include &lt;boost/type_traits/type_with_alignment.hpp&gt; </p> <p> #ifdef _MSC_VER <em> This kind of packing is set within MSVC 9.0 headers. </em> E.g. std::ostream has it. #pragma pack(push,8) #endif /* _MSC_VER */ </p> <p> <em> The issue is gone if Root has no data members struct Root { int a; }; </em> The issue is gone if Root is inherited non-virtually struct A : virtual public Root {}; </p> <p> #ifdef _MSC_VER #pragma pack(pop) #endif /* _MSC_VER */ </p> <p> <em> The class gets alignment 12 for some reason </em> The real-world case that triggered the problem is a user-defined stream class that <em> derived from std::ostream. Such class could not be used with tools involving type_with_alignment. class my_class : </em></p> <blockquote> <p> public A </p> </blockquote> <p> { public: </p> <blockquote> <p> <em> The issue is gone if the type is not a boost::function. The signature doesn't matter. typedef boost::function0&lt; void &gt; function_type; function_type m_function; </em></p> </blockquote> <p> }; </p> <p> struct alignment_of_hack { </p> <blockquote> <p> char c; my_class t; </p> </blockquote> <p> }; </p> <p> int main(int, char*[]) { </p> <blockquote> <p> /* </p> <blockquote> <p> boost::type_with_alignment&lt; </p> <blockquote> <p> boost::alignment_of&lt; </p> <blockquote> <p> my_class </p> <blockquote class="citation"> <p> ::value ::type obj; </p> </blockquote> </blockquote> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <p> return static_cast&lt; int &gt;(&amp;obj != NULL); */ </p> </blockquote> <p> std::cout &lt;&lt; "True alignment of my_class is: " &lt;&lt; <span class="underline">alignof(my_class) &lt;&lt; std::endl; std::cout &lt;&lt; "Size of my_class is: " &lt;&lt; sizeof(my_class) &lt;&lt; std::endl; </span></p> </blockquote> <blockquote> <p> alignment_of_hack h; </p> </blockquote> <blockquote> <p> std::cout &lt;&lt; "Size of alignment_hack is: " &lt;&lt; sizeof(h) &lt;&lt; std::endl; std::cout &lt;&lt; "Offset of my_class in alignment_hack is: " &lt;&lt; (reinterpret_cast&lt;char*&gt;(&amp;(h.t)) - reinterpret_cast&lt;char*&gt;(&amp;h)) &lt;&lt; std::endl; </p> </blockquote> <blockquote> <p> my_class a<a class="changeset" href="https://svn.boost.org/trac10/changeset/10" title="*** empty log message *** ">[10]</a>; </p> </blockquote> <blockquote> <p> for(int i = 0; i &lt; 10; ++i) { </p> <blockquote> <p> int location = (reinterpret_cast&lt;char*&gt;(&amp;(a[i])) - reinterpret_cast&lt;char*&gt;(a)); std::cout &lt;&lt; location &lt;&lt; " " &lt;&lt; (location % <span class="underline">alignof(my_class)) &lt;&lt; std::endl; </span></p> </blockquote> <p> } </p> </blockquote> <blockquote> <p> return 0; </p> </blockquote> <p> } </p> Ticket John Maddock Wed, 04 Jun 2008 17:00:20 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/1946#comment:2 https://svn.boost.org/trac10/ticket/1946#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/46127" title="Enable alignof intrinsic support. Also fixes #1946.">[46127]</a>) Enable alignof intrinsic support. Also fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/1946" title="#1946: Bugs: [type_traits] type_with_alignment fails on non-power-of-2 alignment (closed: fixed)">#1946</a>. </p> Ticket