C++, statically detect base classes with differing addresses?

雨燕双飞 提交于 2019-12-02 02:26:20

I don't know how to check what you wan't but note that your assumption is false in presence of empty base classes. Any number of them can share the same offset from the start of the object, as long as they are of different type.

I am trying to solve this exact same issue. I have an implementation that works if you know what member variable is at the beginning of the base class's layout. E.g. if member variable "x" exists at the start of each class, then the following code will work to yield the byte offset of a particular base class layout from the derived class layout: offsetof(derived, base2::x).

In the case of:
struct base1 { char x[16]; };
struct base2 { int x; };
struct derived : public base1, public base2 { int x; };
static const int my_constant = offsetof(derived, base2::x);

The compiler will properly assign "16" to my_constant on my architecture (x86_64).

The difficulty is to get "16" when you don't know what member variable is at the start of a base class's layout.

I am not even sure that this offset is a constant in the first place. Do you have normative wording suggesting otherwise?

I'd agree that a non-const offset would be bloody hard to implement in the absence of virtual inheritance, and pointless to boot. That's besides the point.

Classes do not have a this pointer - instances of classes do, and it will be different for each instance, no matter how they are derived.

What about using

BOOST_STATIC_ASSERT(boost::is_convertible<Derived*,Base*>::value)

as documented in the following locations...

http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html

http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/is_convertible.html

I didn't realize that the compiler would insert this check at runtime, but your underlying assumption isn't entirely correct. Probably not in ways that you care about though: the compiler can use the Empty Base Class Optimization if you happen to inherit from more than one base class with sizeof(base class)==0. That would result in (base class *)(derived *)1==at least one other base class.

Like I said, this probably isn't something you would really need to care about.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!