Subject: [Boost-bugs] [Boost C++ Libraries] #11310: is_virtual_base_of has false positives caused by sizeof alignment
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-05-15 06:14:11
#11310: is_virtual_base_of has false positives caused by sizeof alignment
----------------------------------+-------------------------
Reporter: leandro.gracia.gil@⦠| Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: type_traits
Version: Boost 1.57.0 | Severity: Problem
Keywords: |
----------------------------------+-------------------------
The is_virtual_base_of<Base, Derived> type trait can report virtual bases
in situations when there isn't any. Here's an example code snippet where
it fails:
{{{
#include <iomanip>
#include <iostream>
#include <boost/type_traits.hpp>
struct A { int a; };
struct B : public virtual A {};
struct C : public A { virtual ~C() {} };
int main() {
std::cout << std::boolalpha;
std::cout << "Is A a virtual base of B? " <<
boost::is_virtual_base_of<A, B>::value << std::endl;
std::cout << "Is A a virtual base of C? " <<
boost::is_virtual_base_of<A, C>::value << std::endl;
return 0;
}
}}}
In the above code both checks are true despite A being a non-virtual base
of C. The reason for this is that alignment is affecting the results from
sizeof and itâs making two different sizes seem equal.
In particular:
{{{
sizeof(is_virtual_base_of_impl<A, C,
mpl::true_>::boost_type_traits_internal_struct_X) == 16
sizeof(is_virtual_base_of_impl<A, C,
mpl::true_>::boost_type_traits_internal_struct_Y) == 16
}}}
However, if we redefine C as packed (example for gcc / clang):
{{{
struct C : public A { virtual ~C() {} } __attribute__((packed);
}}}
Then the sizes do mismatch as expected and the result is correct:
{{{
sizeof(is_virtual_base_of_impl<A, C,
mpl::true_>::boost_type_traits_internal_struct_X) == 16
sizeof(is_virtual_base_of_impl<A, C,
mpl::true_>::boost_type_traits_internal_struct_Y) == 12
}}}
The solution for this problem would be to define the auxiliary types
''boost_type_traits_internal_struct_X'' and
''boost_type_traits_internal_struct_Y'' as packed in such a way that works
across all supported compilers. This might be some combination of ''_
_attribute_ _((packed))'' for gcc/clang, ''#pragma pack'' for the Visual
C++ compiler and others.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11310> 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:50:18 UTC