Help fix my bloated C++ macros!

mortoray

edA‑qa mort‑ora‑y

Posted on February 11, 2018

Help fix my bloated C++ macros!

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.

💖 💪 🙅 🚩
mortoray
edA‑qa mort‑ora‑y

Posted on February 11, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Help fix my bloated C++ macros!
discuss Help fix my bloated C++ macros!

February 11, 2018