02、断言与静态断言
ASSERT:断言
NAME // 准确陈述 assert - abort the program if assertion is false // assert(断言) - 如果断言(assertion)是错误的就终止这个程序。 SYNOPSIS // 概要 #include <assert.h> // assert函数包含在<assert.h> 这个头文件中 void assert(scalar expression); // 函数原型 :void assert(常量 表达式) DESCRIPTION // 描述 This macro(宏指令) can help programmers find bugs in their programs, or handle exceptional cases via(经由) a crash(失败) that will produce limited debugging output. If expression is false (i.e., compares equal to zero), assert() prints an error message to standard error and terminates(终止) the program by calling abort(3). The error message includes the name of the file and function containing the assert() call, the source code line number of the call, and the text of the argument(理由); something like(有点像): prog: some_file.c:16: some_func: Assertion `val == 0' failed. If the macro NDEBUG is defined at the moment <assert.h> was last included, the macro assert() generates(生成) no code, and hence(执行) does nothing at all. It is not recommended(建议) to define NDEBUG if using assert() to detect(检查) error conditions since the software may behave non-deter‐ ministically.
试着翻译一下:(翻译错误的地方请指正)
描述:
这个assert()这个宏指令帮助程序员找程序中的bugs。或者处理经由debug输出限制导致失败的cases。
如果表达式失败,assert()这个宏将打印一个标准错误的信息并且调用abort(3)这个函数来终止这个程序,
这个错误信息包括包含调用asser()宏的函数和包含调用assert()宏的文件名,行号,和理由,有点像:
some_file.c:16: some_func: Assertion `val == 0' failed.
如果宏NDEBUG 是定义在<assert.h>之前,则assert()这个宏不生成代码,什么也不执行。
我们不建议在使用essert()进行error检查时定义define。
////////////////////////////////////////////////////////////////////////////////////////////////
前面说了那么多,梳理一下:
1、assert中文意思叫“断言”,是DEBUG时使用的,换一句话的意思就是,只有在DEBUG时assert()才生效。
2、assert()包含在<assert.h>这个文件中,其
原型为:
void assert(scalar expression);
值得注意:
assert()函数参数已经明确是一个常量表达式。换句话就是布尔表达式。
![](https://img2018.cnblogs.com/i-beta/964704/202002/964704-20200222212137125-1900423952.png)
3、当表达式为false时,assert()会打印出标准的错误信息,这个标准的错误信息如下:
__FILE__
__LINE__
__FUNCTION__
4、文章最后一段也描述了什么情况下assert()不起作用:
就是在#include<assert.h>之前有定义---#define NDEBUG 时,assert()将什么也不执行。
NDEBUG宏由于字面意思,也被用于作为判断debug/release版本的宏,不过这个是编译器、
环境相关的,并不可靠。比如vc中,对生成的release版本项目,默认会定义这个宏,
而gcc并没有定义得用-DNDEBUG参数来定义。
用C语言的一段代码测试一下:
1 #include<stdio.h> 2 #include<assert.h> 3 #include<Windows.h> 4 5 int main(int argc, char* argv[]) 6 { 7 int num = 0; 8 9 assert(num); // 显然表达式是假的,头文件中并没有包含宏定义--#define NDEBUG 10 11 system("pause"); 12 return 0; 13 }
VS2019输出结果:
1 #include<stdio.h> 2 #define NDEBUG 3 #include<assert.h> 4 #include<Windows.h> 5 6 int main(int argc, char* argv[]) 7 { 8 int num = 0; 9 10 assert(num); // 显然表达式是假的,头文件中并没有包含宏定义--#define NDEBUG 11 12 system("pause"); 13 return 0; 14 }
与上一段代码不同这次多加了#define NDEBUG
程序顺利通过。
static_assert():静态断言
![](https://img2018.cnblogs.com/i-beta/964704/202002/964704-20200223130732132-1191927513.png)
![](https://img2018.cnblogs.com/i-beta/964704/202002/964704-20200223132201522-1576616160.png)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
断言与静态断言综合起来比较:
1、断言发生在运行阶段,而静态断言发生在编译阶段,静态断言消灭了很多隐患。