1

是否可以在断言错误上写一条消息?

例如,使用#include <assert.h>,我只能写:

void foo(int a, int b) {
  assert (a != b);
}

但是,在出现错误时,我想查看aand的值b。我怎样才能做到这一点?

4

3 回答 3

8

我通常只是简单地使用assert(a != b && "This is my error message"). 这是有效的,因为char*可以转换为 bool 并且它永远不会是错误的(因为地址不是 0)。

于 2013-05-27T15:46:29.583 回答
7

assert只是一个预处理器宏,如果条件失败调用abort. 您可以使用简单的语句轻松创建自己的if语句,如果失败则打印值并调用abort,如下所示assert

void foo(int a, int b)
{
    if (a != b)
    {
        std::cerr << "My own assertion failed: a = " << a << ", b = " << b << '\n';
        abort();
    }

    /* ... */
}

但是,当您使用 C++ 时,您可能应该抛出异常,可能是std::logic_error

void foo(int a, int b)
{
    if (a != b)
    {
        std::istringstream is;
        is << "Argument mismatch in `foo`: a = " << a << ", b = " << b;
        throw std::logic_error(is.str());
    }

    /* ... */
}
于 2013-05-27T15:12:08.327 回答
1

可以编写自己的断言宏,它可以将表达式分解为子表达式并打印每个子表达式的值;但它需要大量代码来支持它,而标准assert宏在我知道的任何实现中都不会这样做。

有关如何实现这样的事情的示例,请参阅CATCH 测试框架,特别是CHECK宏的实现。

或者,您可以编写宏或函数,如ASSERT_EQUAL(a,b),将每个子表达式作为单独的参数。

或者您可以编写自己的错误处理代码,而无需assert

if (a == b) {
    throw std::runtime_error("foo: a(" + std::to_string(a) + ") must not equal b");
}
于 2013-05-27T15:18:46.397 回答