[应用相关] assert宏

[复制链接]
291|0
 楼主| febgxu 发表于 2023-5-25 16:07 | 显示全部楼层 |阅读模式
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,我们常常这样使用assert宏:


  1. void main()

  2. {

  3.     int* p = NULL;

  4.     p = (int *)malloc(sizeof(int));

  5.     assert(p != NULL);

  6.     ...

  7. }

如果让我来定义assert宏,我可能会定义成如下的形式:

  1. #define assert(exp) if(!exp) _assert(#exp, __FILE__, __LINE__)

上面的宏使用的是语句,在某些情形下,这个宏有一些难以察觉的错误,假如我们有如下的宏调用:

  1. if(x > 0)

  2.     assert(y > x);

  3. else

  4.     assert(x > y);

  5. ...

我们把宏展开:

  1. if(x > 0)

  2.     if(!(y > x))) _assert("y > x", __FILE__, __LINE__);

  3. else

  4.     if(!(x > y)) _assert(" x > y", __FILE__, __LINE__);

  5. ...

由于else默认是跟离它最近的if匹配,我们重新缩进下:

  1. if(x > 0)

  2.     if(!(y > x))) _assert("y > x", __FILE__, __LINE__);

  3.     else

  4.         if(!(x > y)) _assert(" x > y", __FILE__, __LINE__);

  5. ...

这和我们想要的结果是不同的,

我们再来看看系统如何定义assert宏:

  1. #define assert(exp) (void)((exp) || (_assert(#exp, __FILE__, __LINE__), 0))

这个宏是一个表达式,不是语句,利用了||语句的短路现象,||前面的表达式为真时,后面的不再计算,当||之前为假时,才处理后面的表达式;

宏中有个#exp,这里的#号是提取exp的值;

表达式最后有一个0处于逗号运算符之后,这样处理确保整个表达式最后值为0,即为false。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

5088

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部