Add custom messages in assert?

2019-01-12 22:41发布

问题:

Is there a way to add or edit the message thrown by assert? I'd like to use something like

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

Then, the compiler adds line, time and so on...

Is it possible?

回答1:

A hack I've seen around is to use the && operator. Since a pointer "is true" if it's non-null, you can do the following without altering the condition:

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

Since assert shows the condition that failed, it will display your message too. If it's not enough, you can write your own myAssert function or macro that will display whatever you want.



回答2:

Another option is to reverse the operands and use the comma operator. You need extra parentheses so the comma isn't treated as a delimiter between the arguments:

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

(this was copied from above comments, for better visibility)



回答3:

BOOST_ASSERT_MSG(expre, msg)

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

You could either use that directly or copy Boost's code. Also note Boost assert is header only, so you could just grab that single file if you didn't want to install all of Boost.



回答4:

Here's my version of assert macro, which accepts the message and prints everything out in a clear way:

#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();
    }
}

Now, you can use this

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

And in case of failure you will get a message like this:

Assert failed:  MyFunction: requires non-null argument

Expected: ptr != nullptr

Source: C:\MyProject\src.cpp, line 22

Nice and clean, feel free to use it in your code =)



回答5:

As zneak's answer convolutes the code somewhat, a better approach is to merely comment the string text you're talking about. ie.:

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

Since the reader of the assert error will look up the file and line anyway from the error message, they will see the full explanation here.

Because, at the end of the day, this:

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

reads better than this:

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

in terms of human parsing of code ie. readability. Also not a language hack.



回答6:

assert is a macro/function combination. you can define your own macro/function, using __FILE__, __BASE_FILE__, __LINE__ etc, with your own function that takes a custom message



回答7:

Why nobody mentioned the cleanest solution?

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


回答8:

For vc, add following code in assert.h,

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


标签: c++ assert