id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc
11310,is_virtual_base_of has false positives caused by sizeof alignment,leandro.gracia.gil@…,John Maddock,"The is_virtual_base_of type trait can report virtual bases in situations when there isn't any. Here's an example code snippet where it fails:
{{{
#include
#include
#include
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::value << std::endl;
std::cout << ""Is A a virtual base of C? "" << boost::is_virtual_base_of::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::boost_type_traits_internal_struct_X) == 16
sizeof(is_virtual_base_of_impl::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::boost_type_traits_internal_struct_X) == 16
sizeof(is_virtual_base_of_impl::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.",Bugs,closed,To Be Determined,type_traits,Boost 1.57.0,Problem,duplicate,,