自定义Assert

断言

断言(Assert)对于程序调试非常重要,在一些库的实现中,为了检查中间计算过程的错误,可以使用断言进行检查;C++中有标准的assert库,但本文中,尝试写一写自定义assert的实现,以更好地辅助我们进行debug。

原则
  • 断言内的条件是无条件为true的,如果断言失败,意味着程序逻辑错误,即程序存在bug,应当被修复;
  • 断言只在debug模式下使用,在release模式,应当屏蔽掉断言,以避免对运行速度和binary文件的大小的影响;
  • 断言不应该用来作为输入的合法性检查,也不应该用于异常处理,只作为debug目的,并且assert检查失败的情况按照正常情况应该永远不会出现;
自定义assert

常见的assert形式如下:

  • assert(expr)
  • assert_eq(expr)
  • assert_ne(expr)
  • ...

我们通过C++宏来实现以上assert:

#include 
#define MY_ENABLE_ASSERT

void assert_fail(const char* file, int line, const char* func,
                              const char* expr, const std::string& msg) {
    (void)file;
    (void)line;
    (void)func;
    (void)expr;
    (void)msg;
    std::string err_msg = std::string("Assertion fails:") + expr + ", message:" + msg +
                       ", at " + file + ":" + std::to_string(line) + ":" + func;
    std::cout << err_msg << std::endl;
    std::terminate();
}

#ifdef MY_ENABLE_ASSERT
#define MY_ASSERT(expr)                                                     \
    do {                                                                    \
        if(!(expr)) {                                                       \
            assert_fail(__FILE__, __LINE__, __func__, #expr, "");           \
        }                                                                   \
    } while(0)

#define MY_ASSERT_EQ(a, b)                                                 \
    do {                                                                   \
        using std::to_string;                                              \
        if ((a) != (b)) {                                                  \
            assert_fail(__FILE__, __LINE__, __func__, #a " == " #b,        \
                        std::to_string(a) + " != " + std::to_string(b));   \
        }                                                                  \
    } while (0)

#define MY_ASSERT_NE(a, b)                                                 \
    do {                                                                   \
        using std::to_string;                                              \
        if ((a) == (b)) {                                                  \
            assert_fail(__FILE__, __LINE__, __func__, #a " == " #b,        \
                        std::to_string(a) + " != " + std::to_string(b));   \
        }                                                                  \
    } while (0)
#else
#define MY_ASSERT(expr) (void)0
#define MY_ASSERT_EQ(expr) (void)0
#define MY_ASSERT_NE(expr) (void)0
#endif

int main(int argc, char** argv) {
    int data[5] = {1,2,3,4,5};
    // int index = 5;
    // MY_ASSERT(index < 5);
    // std::cout << data[index] << std::endl;
    // MY_ASSERT_EQ(3,3);
    MY_ASSERT_NE(2,2);
}

以上程序输出:

Assertion fails:2 == 2, message:2 != 2, at my_assert.cpp:54:main

你可能感兴趣的:(自定义Assert)