您的位置:首页 > 其它

C 02 关键字:assert动态断言与BOOST提供的静态断言

2013-12-31 12:03 274 查看
1.提高程序健壮性之assert使用 这里的assert是动态断言 意味着是在程序运行期判断条件是否为真

1.1
assert宏的原型定义在<assert.h>中,
其作用是如果它的条件返回错误,则终止程序执行,
原型定义:
  #include <assert.h>
  void assert( int expression );
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,
然后通过调用 abort 来终止程序运行。

1.2
  编写能正常运行的程序很难;编写在错误情况下仍然表现的很“优雅”的程序更难。这篇文章将和大家讨论一些编程技巧, 可以使我们在运行中的程序中早点发现错误,检测和从问题中恢复。那就先讨论下断言(assert)的使用吧。 在编码时,有一个好的目标应该时刻铭记在心,那就是:应该想办法让bug或者异常错误尽早使得程序down掉,或者出现错误。 因为这样可以帮助你在开发和测试阶段尽快找出bug。有一些错误不会无缘无故的暴露自己,往往是产品都到了客户手上,这些错误才会显现出来。 一个最简单的检查异常条件的方法是使用标准C的assert宏,它的参数是一个bool表达式。   
  当表达式为假时,程序会退出。在退出之前打印错误消息,包括源文件,行号,和表达式本身。断言非常有用, 它提供了一个作用于程序内部的广泛的一致性检查方法。例如,使用断言测试函数参数的有效性,测试异常的返回值等等。 每一个断言的使用不仅提供了一个程序运行时的条件检查,也像一个对源代码级别的程序操作的说明性文档。 如果你的程序包含了一个断言,也就是告诉那些阅读你源代码的人,在你的源代码中,在程序的这一点,这个条件应该为真, 如果不为真,那就是一个bug。 当然,在追求性能的代码中,使用assert会降低程序性能。但是你放心,在编译时加入NDEBUG参数编译器就可以对assert进行 预处理,从而移除它。正因为在预处理时可能移除assert,那你使用时就得小心了。什么时候用,什么时候不用就成了一个问 题。通常,你不应该在assert内部调用函数,定义变量,或者使用改变值的操作符,如++。
1.3
  我们假设你这样使用了:

  for (i = 0; i <= 100; ++i)

  assert (do_something () == 0);


  然后,你可能会发现这样会使得性能大大降低,

  从而在创新编译使使用NDEGUG参数。这将移除整个assert宏,这就将do_something( )也被移除了,再也不被调用。
  为了纠正错误,你应该这样写:

  for (i = 0; i <= 100; ++i)

  {

    int status = do_something ();

    assert (status == 0);

  }


  另外应该铭记在心的是,不要用assert去检查无效的输入。用户可不喜欢自己在输入时程序直接退出,即便是输入错误,程序最好也有友好的响应。所以,你应该对无效输入进行检查,并输出一些有用的提示信息。只在程序运行中进行内部检查时使用断言。

1.4
  在这里,我会给出一些比较好的在程序中使用assert的地方: (1)空指针检查。例如,针对一个函数的参数进行空指针检查。你可以这样使用:assert (pointer != NULL);, 产生的错误会像这样:Assertion ‘pointer != ((void *)0)’ failed。这样,当出现空指针时,你的程序就会退出, 并很好的给出错误信息。 (2)检查函数参数的值。例如,如果一个函数只能在它的一个参数foo为正值的时候被调用,你可以在函数开始时这样写: assert (foo > 0);,这将帮助你检测函数的错误使用,这也给源代码阅读者很清晰的印象,那就是在这里对函数的参数值 有限制。

2.BOOST_STATIC_ASSERT boost库提供的静态断言 意味着是在编译期判断条件是否为真 一般用于泛型编程(模板)的地方
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: