在assert中添加自定义消息?

时间:2010-09-11 22:39:25

标签: c++ assert

有没有办法添加或编辑断言抛出的消息?我想使用像

这样的东西
assert(a == b, "A must be equal to B");

然后,编译器添加时间等等......

有可能吗?

10 个答案:

答案 0 :(得分:199)

我见过的黑客是使用&&运算符。如果指针“为真”,如果它是非空的,你可以在不改变条件的情况下执行以下操作:

assert(a == b && "A is not equal to B");

由于assert显示失败的情况,它也会显示您的消息。如果还不够,您可以编写自己的myAssert函数或宏来显示您想要的任何内容。

答案 1 :(得分:34)

另一种选择是反转操作数并使用逗号运算符。您需要额外的括号,因此逗号不会被视为参数之间的分隔符:

assert(("A must be equal to B", a == b));

(这是从上面的评论中复制的,以获得更好的可见性)

答案 2 :(得分:18)

BOOST_ASSERT_MSG(expre, msg)

http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html

您可以直接使用它或复制Boost的代码。另请注意,Boost断言仅是标头,因此如果您不想安装所有Boost,则可以抓取该单个文件。

答案 3 :(得分:18)

这是我的断言宏版本,它接受消息并以清晰的方式打印出所有内容:

#include <iostream>

#ifndef NDEBUG
#   define M_Assert(Expr, Msg) \
    __M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
#   define M_Assert(Expr, Msg) ;
#endif

void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
    if (!expr)
    {
        std::cerr << "Assert failed:\t" << msg << "\n"
            << "Expected:\t" << expr_str << "\n"
            << "Source:\t\t" << file << ", line " << line << "\n";
        abort();
    }
}

现在,您可以使用此

M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");

如果失败,你会得到这样的信息:

  

断言失败:MyFunction:需要非空参数

     

预期:ptr!= nullptr

     

来源:C:\ MyProject \ src.cpp,第22行

干净整洁,随意在你的代码中使用它=)

答案 4 :(得分:7)

由于zneak的回答在某种程度上使代码回旋,更好的方法是仅仅评论您正在谈论的字符串文本。即:

assert(a == b); // A must be equal to B

由于断言错误的读者将从错误消息中查找文件和行,因此他们将在此处看到完整的解释。

因为,在一天结束时,这是:

assert(number_of_frames != 0); // Has frames to update

读得比这更好:

assert(number_of_frames != 0 && "Has frames to update");

就人类解析代码而言。可读性。也不是语言黑客。

答案 5 :(得分:1)

断言是一个宏/函数组合。你可以使用__FILE____BASE_FILE____LINE__等定义自己的宏/函数,使用自己的函数来获取自定义消息

答案 6 :(得分:0)

为什么没有人提到最干净的解决方案?

bool AMustBeEqualToB = (a == b);
assert(AMustBeEqualToB);

答案 7 :(得分:0)

您也可以只编写自己的自定义断言函数。一个非常简单的例子:

bool print_if_false(const bool assertion, const char* msg) {
    if(!assertion) {
        // endl to flush
        std::cout << msg << std::endl;
    }
    return assertion;
}

int main()
{
    int i = 0;
    int j = 1;
    assert(print_if_false(i == j, "i and j should be equal"));
    return 0;
}

play with the code.

断言为Assertion print_if_false(i == j, "i and j should be equal")

答案 8 :(得分:0)

如果断言是在类中完成的,另一种方法是调用具有自描述名称的静态谓词函数。如果断言失败,消息将已经包含谓词的漂亮且自描述的名称。

例如:

static bool arguments_must_be_ordered(int a, int b) {return a <= b;}

void foo(int a, int b)
{
    assert(arguments_must_be_ordered(a, b));
    // ...
}

您甚至可能希望将该谓词函数设为公开,以便类的用户可以自己验证前提条件。

即使没有为发布版本禁用 assert,如果谓词相当简单,编译器也可能会内联该谓词。

同样的方法可用于需要注释的复杂 if 条件。只需调用自描述谓词函数,而不是注释。

答案 9 :(得分:-5)

对于vc,在assert.h中添加以下代码,

#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )