Help fix my bloated C++ macros!

edA‑qa mort‑ora‑y - Feb 11 '18 - - Dev Community

I've been working on error messages in Leaf, these use a lot of macros to reduce code size and keep speed up. I'm not too happy about them. I even started writing an article on how to minimize them, but realized I don't know how. Do any C++ gurus have some ideas?

The Macro

One macro invocation to test for a user-code error looks like below (this checks the condition that an index into a tuple is within range).

CHECK_RETURN( ctx, ex, index < tup->sub.size(), "index-out-of-range" );
Enter fullscreen mode Exit fullscreen mode

The macro looks like this:

#define CHECK_RETURN( ctx_, stmt_, cond_, reason_, ... )    \
    if( !(cond_) ) { (ctx_).mark_failed(*(stmt_)).error( *(stmt_), (reason_),\
        { LOGGER_COND(cond_) }, { __VA_ARGS__ } ); \
        return (stmt_); }

Enter fullscreen mode Exit fullscreen mode

Where LOGGER_COND adds more info (assume S__LINE__ is the string version of __LINE__)

#define LOGGER_COND(cond_) util::logger::item_debug_loc( __FILE__ "@" S__LINE__ ), \
    util::logger::item_debug_cond( #cond_ )
Enter fullscreen mode Exit fullscreen mode

The Reason

This macro fulfills a few requirements:

  • It reduces redundant code (this type of macro is used hundreds of times in the source code)
  • The costly bit, of creating the items for the logger, is not done unless the condition fails
  • It reports common information to the logger
  • It marks the compilation failed in a consistent manner

But Yuck!

But I just don't like this. I'm already keeping the macro short, but somehow I feel as though it could get shorted. The need for the deferred evaluation, and ultimate return statement prevent me from writing a function that does the same thing -- unless, and this is where I'm hoping, there is a C++14/17 feature that somehow helps me.

Notes

The .../__VA__ARGS__ part in the macro is for places where I pass extra information:

CHECK_RETURN( ctx, field, msym, "unknown-field", util::logger::item_symbol(field->field) );
Enter fullscreen mode Exit fullscreen mode

There are several redundant variants of the macro, some throw, others take slightly different parameters. I'd like a cleaner solution.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player