我希望将实现断言宏作为C ++中的方法,如.NET Framewrk。
例如在C#中,我们可以像这样调用assert方法:
Debug.Assert(index > -1);
我希望实现断言这样的东西:
#include <assert.h>
class debug
{
public:
static void my_asset(<condition>) // like assert macro
{
// ?
}
};
使用此课程时:
debug::my_asset(index > -1); // Actually should be called assert(index > -1);
由于
修改:
我想在调用debug::my_asset(index > -1);
时,它显示正确的文件名和行号,它就像C ++资产宏一样。
答案 0 :(得分:6)
断言assert
(<assert.h>
或<cassert>
)中有几个特征值得关注:
如果不使用宏,则无法在C ++中执行这些操作。
答案 1 :(得分:3)
获取行号,文件和文本版本的唯一方法是通过宏。但是:
#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,
}
此代码以奇怪的方式工作。第一个x
是断言表达式本身,计算为true或false,告诉my_assert要做什么。 #x
是一个神奇的预处理器命令,它生成x
的char *版本,因此我们可以显示它。 __FILE__
将替换为文件名,__LINE__
将替换为行号。 (因为它是一个宏,它具有与调用函数相同的行号)。
当您输入debug::myassert(sizeof(int)==4);
时,预处理程序会显示“我知道myassert(whatever)
是什么!”并取代它。因此它将所有内容替换为:debug::my_assert(sizeof(int)==4, "sizeof(int)==4", "main.cpp", 27);
,这是一行有效的代码。因此,如果sizeof(int)例如是8(它在某些机器上),则第一个参数是false
,并且该行显示为在27的main.cpp中的assert sizeof(int)== 4。 “
答案 2 :(得分:2)
static void my_asset(bool cond) // like assert macro
{
::assert(cond);
}
不起作用?
答案 3 :(得分:2)
你可以
void debug::my_assert(bool cond) {
ASSERT(cond);
}
这可能会导致断言失败时会导致异常。
它比宏没有那么有用,因为my_assert
无法看到失败的条件 - 你会得到一个断言失败但没有有用的解释(尽管你会得到一个准确的堆栈跟踪在调试器中。)
另见Ken的原因,为什么宏更有帮助。