当前位置:  开发笔记 > 编程语言 > 正文

断言和NDEBUG

如何解决《断言和NDEBUG》经验,为你挑选了2个好方法。

在阅读了一些关于异常滥用的线程之后(基本上说,如果函数前置条件不正确,你不想解开堆栈 - 可能表示你的所有内存都已损坏或同样危险)我正在考虑使用assert()更多经常.以前我只使用assert()作为调试工具,我认为这是很多C++程序员使用它的方式.我担心我的错误处理部分会被未来某个时候引入运行时构建的NDEBUG #define关闭.有没有办法绕过这个并让其他人对此有问题(即我应该担心它)?

谢谢,帕特

编辑:我正在阅读的线程的重点是,如果您的应用程序确实存在错误,那么展开堆栈可能会损坏系统,例如,如果析构函数将某些内容写入文件并且文件句柄已损坏.我不建议使用assert进行正常的错误处理.我目前的用例非常弱,但看看你的想法:


  //check later code won't crash the system
  if( buf.length() % 2 )
    return false;
  // do other stuff that shouldn't affect bufs length
  //copy 2 bytes into buf at a time, if length is odd then don't know 
  //what will happen so use assert to make sure it can't damage anything
  assert( !(buf.length() % 2) );
  for( i = 0; i != buf.length(); i += 2 )
    memcpy( buf + i, data, 2 );
 

edit2:讨论在这里:http: //groups.google.com/group/comp.lang.c++.moderated/browse_frm/thread/80083ac31a1188da



1> David Poole..:

您可以构建自己的断言而不是使用库存C断言.您的断言不会被禁用.

看一下在/usr/include/assert.h(或者任何地方)中如何实现assert().它只是一些预处理器魔术,最终称为"断言失败"功能.

在我们的嵌入式环境中,我们一直在替换assert().



2> Larry Gritz..:

我喜欢定义自己的断言宏.我总是进行两次ASSERT测试(即使对于优化的构建),DASSERT只对调试版本有影响.您可能希望默认为ASSERT,但如果测试的内容很昂贵,或者性能敏感区域的内部循环内的断言可以更改为DASSERT.

另外,请记住,断言应仅用于完全无意义的条件,这些条件表明程序中存在逻辑错误,并且无法从中恢复.这是对编程正确性的测试.永远不应该使用断言来代替错误处理,异常或健壮性,并且你永远不应断言与格式错误或不正确的用户输入相关的任何内容 - 这样的事情应该优雅地处理.断言只是一个受控制的崩溃,您有机会输出一些额外的调试信息.

这是我的宏:

/// ASSERT(condition) checks if the condition is met, and if not, calls
/// ABORT with an error message indicating the module and line where
/// the error occurred.
#ifndef ASSERT
#define ASSERT(x)                                                      \
    if (!(x)) {                                                         \
        char buf[2048];                                                 \
        snprintf (buf, 2048, "Assertion failed in \"%s\", line %d\n"    \
                 "\tProbable bug in software.\n",                       \
                 __FILE__, __LINE__);                                   \
        ABORT (buf);                                                    \
    }                                                                   \
    else   // This 'else' exists to catch the user's following semicolon
#endif


/// DASSERT(condition) is just like ASSERT, except that it only is 
/// functional in DEBUG mode, but does nothing when in a non-DEBUG
/// (optimized, shipping) build.
#ifdef DEBUG
# define DASSERT(x) ASSERT(x)
#else
# define DASSERT(x) /* DASSERT does nothing when not debugging */
#endif

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有