0
#include <cassert>

struct a
{
    virtual ~a() {}
    char a_[10];
};

struct b
{
    virtual ~b() {}
    char b_[20];
};

struct c : public a
{
    virtual ~c() {}
    char c_[15];
};

struct d : public b, a
{
    virtual ~d() {}
    char d_[5];
};

int main()
{
    a a_;
    c c_;
    d d_;

    a* a__ = &a_;
    a* c__ = &c_;
    a* d__ = &d_;

    assert((void*)&a_ == (void*)a__);
    assert((void*)&c_ == (void*)c__);
    assert((void*)&d_ == (void*)d__); // error on most compiler
}

I'm looking for a way to test void* casting safety among class inheritance graph which can detect third assertion in compile time.

template<typename Base, typename Derived>
struct test
{
    enum {
        is_safe = (static_cast<Derived*>(static_cast<Base*>(nullptr)) == nullptr)
    };
};

My intention is described in above code, but it won't be compiled because casting is not constant expression. Is it possible to check it in platform/compiler independent way?

summerlight
  • 882
  • 7
  • 16

1 Answers1

1

According to the standard, casting from X to void* and then from void* to Y is only well-defined if X is the same as Y. Everything else is undefined behavior. Therefore the only possible portable, standard-conforming definition of test is this:

template<typename Base, typename Derived>
struct test
{
    enum {
        is_safe = false;
    };
};

template <typename X>
struct test<X, X>
{
    enum {
        is_safe = true;
    };
};
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243