在c ++ 17中更好地声明宏替换

时间:2019-07-03 17:31:49

标签: c++ gcc clang c++17 assert

要比c中的传统assert宏转储更多信息,我实现了自己的better_assert宏,从而可以打印其他调试信息。

因此可以替换

assert( a == b );

better_assert( a == b, "Error: expect a == b, but a = ", a, " and b = ", b );

实现代码如下:

constexpr int debug_mode = 1;

namespace xxxxxxxx
{   // for macro `better_assert`
    template< typename... Args >
    void print_assertion(std::ostream& out, Args&&... args)
    {
        if constexpr( debug_mode )
        {
            out.precision( 20 );
            (out << ... << args) << std::endl;
            abort();
        }
    }
}

#ifdef better_assert
#undef better_assert
#endif
#define better_assert(EXPRESSION, ... ) ((EXPRESSION) ? (void)0 : xxxxxxxx::print_assertion(std::cerr, "[Assertion Failure]: '", #EXPRESSION, "' in File: ", __FILE__, " in Line: ",  __LINE__ __VA_OPT__(,) __VA_ARGS__))         

具有类似的测试代码

    int a = 1;
    int b = 2;
    better_assert( a == 1 );
    better_assert( a == b, "Error: expected a == b, but a = ", a, " and b = ", b );

gcc 9.1.0接受此代码没有任何问题,但是clang 8.0.0拒绝了它,并显示错误消息:

prog.cc:28:5: error: expected ')'
    better_assert( a == 1 );
    ^
prog.cc:22:192: note: expanded from macro 'better_assert'
#define better_assert(EXPRESSION, ... ) ((EXPRESSION) ? (void)0 : xxxxxxxx::print_assertion(std::cerr, "[Assertion Failure]: '", #EXPRESSION, "' in File: ", __FILE__, " in Line: ",  __LINE__ __VA_OPT__(,) __VA_ARGS__))
                                                                                                                                                                                               ^
prog.cc:28:5: note: to match this '('
prog.cc:22:92: note: expanded from macro 'better_assert'
#define better_assert(EXPRESSION, ... ) ((EXPRESSION) ? (void)0 : xxxxxxxx::print_assertion(std::cerr, "[Assertion Failure]: '", #EXPRESSION, "' in File: ", __FILE__, " in Line: ",  __LINE__ __VA_OPT__(,) __VA_ARGS__))
                                                                                           ^
prog.cc:29:5: error: expected ')'
    better_assert( a == b, "Error: expected a == b, but a = ", a, " and b = ", b );
    ^
prog.cc:22:192: note: expanded from macro 'better_assert'
#define better_assert(EXPRESSION, ... ) ((EXPRESSION) ? (void)0 : xxxxxxxx::print_assertion(std::cerr, "[Assertion Failure]: '", #EXPRESSION, "' in File: ", __FILE__, " in Line: ",  __LINE__ __VA_OPT__(,) __VA_ARGS__))
                                                                                                                                                                                               ^
prog.cc:29:5: note: to match this '('
prog.cc:22:92: note: expanded from macro 'better_assert'
#define better_assert(EXPRESSION, ... ) ((EXPRESSION) ? (void)0 : xxxxxxxx::print_assertion(std::cerr, "[Assertion Failure]: '", #EXPRESSION, "' in File: ", __FILE__, " in Line: ",  __LINE__ __VA_OPT__(,) __VA_ARGS__))
                                                                                           ^
2 errors generated.

此问题可能与仅gcc宏__VA_OPT____VA_ARGS__有关。 我的问题是,有没有一种方法可以使此better_assert宏与clang一起移植?

在线代码供您参考:https://wandbox.org/permlink/ggcafJ5zbGrg5ZTx


我注意到c ++ 20中的__VA_OPT__建议。也许这是解决此问题的最佳方法?

0 个答案:

没有答案