1 什么是断言
在C/C++语言中,断言是一种用于调试程序的工具,它用于验证程序在运行时的假设条件是否成立。断言通常用于检测代码中可能存在的逻辑错误或不符合预期的情况。
2 assert宏
C/C++语言中的断言通过
宏实现,其通常在assert
头文件中定义。<assert.h>
assert
宏的参数通常是一个条件表达式或逻辑表达式,如果表达式求值为false
,assert
宏就在stdeer
中写入一条包含出问题的文件和行号的错误信息,并调用abort()
函数终止程序。
assert
宏的基本定义如下:
#ifdef NDEBUG #define assert(expression) ((void)0) #else #define assert(expression) \ ((expression) ? (void)0 : __assert_fail(#expression, __FILE__, __LINE__, __func__)) #endif
NDEBUG
宏:当定义了NDEBUG
宏时,
宏会被定义为一个空操作,即assert
((void)0)
:当没有定义assert(expression)
NDEBUG
宏时,
宏会检查assert
expression
是否为真。如果
为假(即为 0),则会调用expression
函数,并传递断言失败的信息,包括断言表达式、文件名、行号和函数名。__assert_fail
函数:这个函数负责处理断言失败的情况。它通常会打印错误信息并终止程序执行。其具体实现依赖于标准库的实现,可以是一个标准的错误报告和终止机制。__assert_fail
宏的基本使用语法如下:assert
#include <assert.h> assert(expression);
:其是一个布尔表达式。如果expression
的值为假(即为 0),则expression
宏会输出一条错误消息,并终止程序的执行。如果assert
的值为真(即非 0),则expression
不会做任何操作,程序继续执行。assert
3 _Static_assert宏
在C11标准中,新增了一个_Static_assert
宏,其作用类似于
,只不过assert
宏是在程序运行时检测表达式,而assert
_Static_assert
宏是在程序编译时检测表达式。因此,
宏会导致正在运行的程序中止,而assert
_Static_assert
宏会导致程序无法通过编译。
_Static_assert
宏接受两个参数,第一个参数是整形常量表达式,第二个参数是字符串。如果第一个参数求值为false
,则编译器会报告第二个参数字符串并停止编译。
4 使用示例
4.1 使用断言
#include <stdio.h> #include <assert.h> int main() { int x = 5; assert(x == 5); // 断言 x 等于 5 printf("x is 5\n"); assert(x == 10); // 断言 x 等于 10(这会失败) printf("x is 10\n"); return 0; }
在上面的代码中,第一次断言
是成功的,程序继续执行并打印x == 5
,第二次断言x is 5
是失败的,程序会终止,并打印断言失败的信息。x == 10
4.2 禁用断言
断言在程序调试阶段非常有用,但是在性能关键的代码中,断言可能会增加额外的开销,因此通常会在发布版本中禁用。
我们可以通过定义
宏来禁用所有断言,一旦定义了NDEBUG
NDEBUG
,所有的assert
宏将被预处理为一个空语句,不会进行任何检查。定义
宏的通常做法是在编译时加上NDEBUG
参数,或者在包含-DNDEBUG
<assert.h>
头文件之前使用#define NDEBUG
,如下所示:
#define NDEBUG #include <assert.h>