venkysmarty
venkysmarty

Reputation: 11441

C++ compile time checker using templates

I am having following code which is taken from modern C++ design. While i am using it i am getting compiation error i think invalid sizeof opearand. Can any one point out what is the problem. Thanks!

template<bool>
struct CompileTimeChecker {
    CompileTimeChecker(...);
};

template<>
struct CompileTimeChecker<false> {
};

#define STATIC_CHECK(expr, msg) \
{\
class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
}

template <class To, class From>
To safe_reinterpret_cast(From from) {
    STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow);
    return reinterpret_cast<To>(from);
}

int main(void)
{
    int a[20];
    void* somePointer = a;
    char c = safe_reinterpret_cast<int>(somePointer);
}

Error:

d:\technical\c++study\readparsing\readparsing\addressconv.cpp(29) : error C2066: cast to function type is illegal 1> d:\technical\c++study\readparsing\readparsing\addressconv.cpp(37) : see reference to function template instantiation 'To safe_reinterpret_cast(From)' being compiled 1> with 1> [ 1> To=int, 1> From=void * 1> ] 1>d:\technical\c++study\readparsing\readparsing\addressconv.cpp(29) : error C2070: 'CompileTimeChecker<__formal> (safe_reinterpret_cast::ERROR_Destination_Type_Too_Narrow (__cdecl *)(void))': illegal sizeof operand 1> with 1> [ 1> __formal=true 1> ]

Upvotes: 2

Views: 408

Answers (2)

Olli Etuaho
Olli Etuaho

Reputation: 303

Like AProgrammer pointed out, the (void)sizeof isn't getting swallowed by the compiler. I suggest removing the parentheses from the sizeof, like this:

(void)sizeof CompileTimeChecker<(expr) != 0>((ERROR_##msg()));\

That seems to make g++ accept it, and interpret it the way it was probably meant to.

If that (void)sizeof keeps giving you trouble, you can get the static checking functionality without it too, for example by initializing a CompileTimeChecker variable:

CompileTimeChecker<(expr) != 0> a((ERROR_##msg()));\

Upvotes: 1

AProgrammer
AProgrammer

Reputation: 52334

Yet another strike for the most vexing parse...

sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))

Is the same as

class Foo {};
class Bar {};
sizeof(Foo((Var()));

and as Foo(Var) can be interpreted either as a type (function taking a (function without an argument an returning a Var) and returning a Foo), it is so.

Upvotes: 4

Related Questions