#define ASSERT(f)  (void) ((f) || !AfxAssertFailedLine(THIS_FILE, __LINE__) || (AfxDebugBreak(), 0))
以上是ASSERT宏定义,谁能说一下,它是如何工作的?

解决方案 »

  1.   

    复制来的
    。    二、ASSERT宏    ASSERT宏能够计算作为参数传递的表达式值。如果表达式为真,则执行继续。否则,程序显示一个消息并中断。此时可以选择忽略错误、终止程序或进入调试器。下面是如何在函数中应用ASSERT宏验证参数的一个例子: void foo(char* p,int size) { ASSERT(p != 0); // 验证缓冲区指针 ASSERT((size >= 100); // 确认缓冲区大小至少为100字节 // foo 函数的其它计算过程 }    如果没有定义_DEBUG预处理符,则该语句不会真正生成代码。Visual C++会在调试模式编译时自动定义_DEBUG,而在发行模式下,该预处理符是不存在的。如果定义了_DEBUG,则上述两个断言生成的代码类如: //ASSERT(p != 0); do { if(!(p != 0) && AfxAssertFailedLine(__FILE__, __LINE__)) AfxDebugBreak(); } while(0); //ASSERT((size >= 100); do { if(!(size >= 100) && AfxAssertFailedLine(__FILE__,__LINE__)) AfxDebugBreak(); }while(0);    do-while结构在一个单独的语句块之内封装了整个断言操作。if语句计算断言表达式,如果值为0则调用AfxAssertFailedLine()。AfxAssertFailedLine()显示消息框并提供 “Abort,Retry,or Ignore”选择,如果选择Retry则调用AfxDebugBreak(),并由此激活调试器。    和AfxAssertFailedLine()的简单目的(即显示对话框以供选择)相比,它的实现显得非常复杂。该函数的源代码在afxasert.cpp内,可以发现它使用了一些特殊的函数以确保消息框正确显示。举个例子,如果断言失败是在程序发送WM_QUIT消息之后的某个位置,则AfxAssertFailedLine()为了显示消息框必须临时地从队列中删除这个消息。    传递给AfxAssertFailedLine()的参数__FILE__ 和 __LINE__分别为代表程序文件名和当前行号的预处理符号。它们由ANSI标准定义,由编译器自动生成具体数值。
      

  2.   

    它会输出错误的行数和源文件名,并暂停执行
    实际上这个断言可以这样解释
    首先是#define ASSERT(f)也就是说后面是这个宏的具体定义了,宏的参数是f
    后面呢(void)这个没有什么实际的作用,只是说明返回空值
    再后面是主要的在这里是一个多个结果相与的函数关系,其中每一个的执行条件如下
    首先是(f)这一部分肯定被执行 如果成立,断言后面不会被执行了,也就是断言通过了,继续执行主程序。
    否则呢,执行!AfxAssertFailed(THIS_FILE,_LINE_)这个函数的两个参数实际上是现在执行的语句所在的文件名和行号,估计它只是简单的输出这些而已,而且它肯定返回0使后面的条件也得到执行
    然后的那一句呢,看名字也知道是暂停或者终止了