I have a macro used around a code statement, to introduce nested exception handling:
#define TRAP_EXCEPTION(statement) \
try \
{ \
try{statement} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
This has been working well until one case raised compiler errors. I managed to construct a minimal example:
TRAP_EXCEPTION
(
std::map<MyType, bool> Map;
)
catch(MyException& e)
{
}
This gives the following errors... how do I fix it (ideally in the macro)?
> error C2143: syntax error : missing '>' before '}'
> error C2976: 'std::map' : too few template arguments
> error C2143: syntax error : missing ';' before '}'
Macros don't understand the template parameters (the angle brackets to be precise), they just see the ,
and think you provided two different parameters to the macro. You need to add round brackets:
TRAP_EXCEPTION
(
(std::map<MyType, bool> Map;)
)
and the macro needs to be changed:
#define UNWRAP(...) __VA_ARGS__
#define TRAP_EXCEPTION(statement) \
try \
{ \
try{UNWRAP statement} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
Note that this would require you to always provide an additional pair of round brackets on the call side.
In your case (since the macro is supposed to take only one statement), you could also use a variadic macro:
#define TRAP_EXCEPTION(...) \
try \
{ \
try{ __VA_ARGS__ } \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
which is probably better since the call side doesn't change and
TRAP_EXCEPTION
(
std::map<MyType, bool> Map;
)
will now work correctly.
The preprocessor doesn't recognise <
and >
as brackets, so interprets the comma as a macro argument separator. You'd have the same problem if the statement contained an unbracketed comma for any other reason (e.g. a comma operator, or commas to separate declarators).
If you really want to abuse the preprocessor like this, you could bodge it to accept any number of macro arguments:
#define TRAP_EXCEPTION(...) \
try \
{ \
try{__VA_ARGS__} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
but I would advise you not to try to do anything clever with macros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With