/**
* Nonempty base class
*/
struct Base
{
int v;
void do_something();
static void do_something(Base* self);
};
/**
* Child class that introduces a vtable pointer
*
* The combination of nonempty base and vtable in child causes an offset
* between pointers to Base and pointers to Child.
*
* Example:
* Child* child = NOT NULL;
* Base* base = child;
* reinterpret_cast<intptr_t>(child) != reinterpret_cast<intptr_t>(base);
*/
struct Child: Base
{
virtual ~Child() = default;
Base* self_as_base();
};
/**
* Unconditional conversion because `this` must not be NULL
*/
Base* Child::self_as_base()
{ return this; }
/**
* Conditional conversion because child may be NULL
*/
Base* child_to_base_ptr(Child* child)
{
return child;
}
/**
* Unconditional conversion because references must not be NULL
*/
Base& child_to_base_ref(Child& child)
{
return child;
}
/**
* Unconditional conversion because `this` must not be NULL
*/
void call_do_something(Child** children, int count)
{
for(int i = 0; i < count; ++i)
children[i]->do_something();
}
/**
* Conditional conversion because child may be NULL
*/
void call_do_something_static_ptr(Child** children, int count)
{
for(int i = 0; i < count; ++i)
Base::do_something(children[i]);
}
/**
* Unconditional conversion because references must not be NULL
*/
void call_do_something_static_ref(Child** children, int count)
{
for(int i = 0; i < count; ++i)
Base::do_something(&static_cast<Base&>(*children[i]));
}
Comments