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.
精彩评论