开发者

How can I implement assert macro as a method?

I want implement assert macro as a method in C++ like .NET Framewrk.

开发者_StackOverflow社区

For example in C# we can invoke assert method like this:

Debug.Assert(index > -1);

and I want implement assert something like this:

#include <assert.h>
class debug
{
  public:

    static void my_asset(<condition>) // like assert macro
    {
      // ?
    }
};

When using this class:

debug::my_asset(index > -1); // Actually should be called assert(index > -1);

Thanks

Edit:

I want when invoking debug::my_asset(index > -1);, It shows correct file name and line number, and it works like C++ asset macro.


There are several features of assert assert (in <assert.h> or <cassert>) that are of interest:

  • that when you're compiling a release build, the assert tests aren't evaluated at all.
  • the error message printed when an assertion fails can tell you the file and line number where your assertion failed
  • it can also tell you the exact code that failed.

You can't do these in C++ without using a macro.


The only way to get the line number, file, and text version is via macro. However:

#include <assert.h>
class debug
{
public:
    static void my_assert(bool passed, const char* assert, const char* file, long line)
    {
        if (passed == false)
            std::cout<<"failed assert "<<assert<<" in "<<file<<" at "<<line<<".\n";
    }
#ifdef NDEBUG
    #define myassert(x) my_assert(true, "", "", 0)
#else 
    #define myassert(x) my_assert(x, #x , __FILE__, __LINE__ )
#endif
};


int main() {
    debug::myassert(sizeof(int)==4);
    return 0,
}

This code works in an oddball way. The first x is the assert expression itself, evaluating to true or false, to tell my_assert what to do. The #x is a magic preprocessor command that makes a char* version of x, so we can display it. __FILE__ is replaced with the filename, and __LINE__ is replaced with the line number. (Since it's a macro, it has the same line number as the calling function).

When you type debug::myassert(sizeof(int)==4);, the preprocessor says "I know what myassert(whatever) is!" and replaces it. So it replaces it all with: debug::my_assert(sizeof(int)==4, "sizeof(int)==4", "main.cpp", 27);, which is a valid line of code. So if sizeof(int) is 8 for instance (it is on some machines), the first parameter is false, and the line is displayed "failed assert sizeof(int)==4 in main.cpp at 27."


static void my_asset(bool cond) // like assert macro
{
  ::assert(cond);
}

Doesn't work?


You could

void debug::my_assert(bool cond) {
    ASSERT(cond);
}

This would work in that it would cause an exception when the assertion failed.

It's a little less helpful than the macro because my_assert can't see what the condition was that failed -- you'll get an assertion failure but no useful explanation (though you'll get an accurate stack trace in a debugger).

Also see Ken's reasons why a macro is more helpful.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜