Re: [Boost-bugs] [Boost C++ Libraries] #1946: [type_traits] type_with_alignment fails on non-power-of-2 alignment

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #1946: [type_traits] type_with_alignment fails on non-power-of-2 alignment
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2008-06-02 16:08:35


#1946: [type_traits] type_with_alignment fails on non-power-of-2 alignment
------------------------------+---------------------------------------------
  Reporter: andysem_at_[hidden] | Owner: johnmaddock
      Type: Bugs | Status: assigned
 Milestone: Boost 1.36.0 | Component: type_traits
   Version: Boost 1.35.0 | Severity: Problem
Resolution: | Keywords: type_traits alignment
------------------------------+---------------------------------------------
Changes (by johnmaddock):

  * status: new => assigned

Comment:

 This is really strange and appears to be an MSVC bug:

 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...

 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!

 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).

 So sometimes MSVC does the wrong thing, and sometimes it corrects itself,
 either way it really confuses our internal logic.

 I'm not really sure what to do here, except perhaps to start using the
 __align_of intrinsic... I'll look into that.

 Regards, John.

 PS I used the code below to deduce the above:

 #include <boost/function.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>

 #ifdef _MSC_VER
 // This kind of packing is set within MSVC 9.0 headers.
 // E.g. std::ostream has it.
 #pragma pack(push,8)
 #endif /* _MSC_VER */

 // The issue is gone if Root has no data members
 struct Root { int a; };
 // The issue is gone if Root is inherited non-virtually
 struct A : virtual public Root {};

 #ifdef _MSC_VER
 #pragma pack(pop)
 #endif /* _MSC_VER */

 // The class gets alignment 12 for some reason
 // The real-world case that triggered the problem is a user-defined stream
 class that
 // derived from std::ostream. Such class could not be used with tools
 involving type_with_alignment.
 class my_class :
     public A
 {
 public:
     // The issue is gone if the type is not a boost::function. The
 signature doesn't matter.
     typedef boost::function0< void > function_type;
     function_type m_function;
 };

 struct alignment_of_hack
 {
    char c;
    my_class t;
 };


 int main(int, char*[])
 {
    /*
     boost::type_with_alignment<
         boost::alignment_of<
             my_class
>::value
>::type obj;

     return static_cast< int >(&obj != NULL);
     */
    std::cout << "True alignment of my_class is: " << __alignof(my_class)
 << std::endl;
    std::cout << "Size of my_class is: " << sizeof(my_class) << std::endl;

    alignment_of_hack h;

    std::cout << "Size of alignment_hack is: " << sizeof(h) << std::endl;
    std::cout << "Offset of my_class in alignment_hack is: " <<
 (reinterpret_cast<char*>(&(h.t)) - reinterpret_cast<char*>(&h)) <<
 std::endl;

    my_class a[10];

    for(int i = 0; i < 10; ++i)
    {
       int location = (reinterpret_cast<char*>(&(a[i])) -
 reinterpret_cast<char*>(a));
       std::cout << location << " " << (location % __alignof(my_class))
 << std::endl;
    }

    return 0;
 }

--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1946#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.


This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:58 UTC