Search code examples
c++visual-studiogccassertdynamic-cast

dynamic_cast in assert Causing Error


I'm using the antiquated Visual Studio 2008 (let me save you the trouble "there's your problem".) This seems to be a problem with Visual Studio: http://rextester.com/XKFR77690 This seems to be a problem with the assert macro: http://ideone.com/bhxMi0

Given these structs:

struct base { virtual ~base() {} };

template <typename T>
struct Foo : base { T foo; };

I can do this:

base* test = new Foo<pair<int, int>>;

if(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) cout << "hello world\n";

But when I use the exact same code as is in the if-statement in an assert: assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) I get an error:

warning C4002: too many actual parameters for macro assert
error C2143: syntax error : missing ',' before ')'

Incidentally I can fix this by using a C-style cast: assert((Foo<pair<int, int>>*)(test) != NULL) But I think that the C-Style cast will do a static_cast not a dynamic_cast which I don't want.


Solution

  • assert is a macro. It's handled by the preprocessor which knows nothing about C++ constructs. So the following:

    assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)
    

    expands to a function-like macro taking two arguments, which in this case are:

    dynamic_cast<Foo<pair<int
    

    and

    int>>*>(test) != NULL
    

    Remember that function-like macro arguments are separated by commas. That is all the preprocessor sees. So in this case it sees 2 arguments instead of the 1 argument required by assert.

    Your C-style cast version works incidentally because of the parentheses, which have higher precedence than the comma. Putting them around the dynamic_cast does the job as well.