如何将assert宏实现为方法?

时间:2011-08-24 22:15:28

标签: c++ methods macros assert

我希望将实现断言宏作为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 ++资产宏一样。

4 个答案:

答案 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的原因,为什么宏更有帮助。