assert 宏、_assert_wassert

计算表达式,如果结果为 false,则打印诊断消息并中止程序。

语法

assert(
   expression
);
void _assert(
   char const* message,
   char const* filename,
   unsigned line
);
void _wassert(
   wchar_t const* message,
   wchar_t const* filename,
   unsigned line
);

参数

expression
计算结果不为零 (true) 或为零 (false) 的标量表达式(包括指针表达式)。

message
要显示的消息。

filename
断言失败的源文件的名称。

line
断言失败处所在的源文件行号。

备注

assert 宏通常用于标识程序开发过程中的逻辑错误。 出现意外情况时可用它停止程序执行,方法是实现 expression 参数来计算仅当程序操作不正确时的 false 。 可通过定义宏 NDEBUG在编译时关闭断言检查。 使用 /DNDEBUG 命令行选项,可以在不修改源文件的情况下来关闭 assert 宏。 可以在包含 <assert.h> 之前使用 #define NDEBUG 指令,以便在源代码中关闭 assert 宏。

assert 宏将在 expression 计算结果为 false (0) 时打印诊断消息并调用 abort 停止程序执行。 如果 expressiontrue (非零),则不执行任何操作。 诊断消息包括失败的表达式、源文件的名称以及断言失败的行号。

诊断消息将用宽 (wchar_t) 字符打印。 因此,它将按预期工作,即使表达式中存在 Unicode 字符也是如此。

诊断消息的目标取决于调用例程的应用程序的类型。 控制台应用程序通过 stderr 接收消息。 在基于 Windows 的应用程序中,assert 调用 Windows MessageBox 函数创建消息框来显示消息以及三个按钮:“中止”、“重试”和“忽略”。 如果用户选择“中止”,则程序将立即中止。 如果用户选择“重试”,则将调用调试器,之后用户可以调试程序,前提是启用了实时 (JIT) 调试。 如果用户选择“忽略”,程序将继续正常执行。 如果存在错误条件,则单击“忽略”可能导致未定义的行为,因为调用代码的前提条件未满足。

若要替代默认输出行为而不考虑应用类型,请调用 _set_error_mode 在 output-to-stderr 和 display-dialog-box 行为之间进行选择。

assert 显示消息后,它将调用 abort,此时将显示一个对话框,其中包含“中止”、“重试”和“忽略”按钮。 abort 将退出程序,因此在调用 assert 后,“重试”和“忽略”按钮不会恢复程序执行。 如果 assert 显示了对话框,则 abort 对话框不会显示。 abort 对话框仅在 assert 将其输出发送给 stderr 时才显示。

由于上述行为,在调试模式下调用 assert 后,始终会显示一个对话框。 下表中捕获了每个按钮的行为。

错误模式 输出到 stderr(控制台/_OUT_TO_STDERR 显示对话框 (Windows/_OUT_TO_MSGBOX)
Abort 立即退出,并显示退出代码 3 立即退出,并显示退出代码 3
Retry abort 期间中断并进入调试程序 assert 期间中断并进入调试程序
Ignore 通过 abort 完成退出 继续执行程序,就好像 assert 未触发(可能会导致未定义的行为,因为调用代码的前提条件未满足)

有关 CRT 调试的详细信息,请参阅 CRT 调试技术

_assert_wassert 函数是内部 CRT 函数。 这两个函数可帮助最大程度地减少在对象文件中支持断言所需的代码。 建议不要直接调用这些函数。

当未定义 NDEBUG 时,C 运行库的发布版本和调试版本中均启用了 assert 宏。 当定义了 NDEBUG 时,该宏虽然可用,但不会计算其参数,因而并不起作用。 启用后,assert 宏会调用 _wassert 用于实现。 其他断言宏 _ASSERT_ASSERTE_ASSERT_EXPR 也可用,但它们只有在已定义 _DEBUG 宏的情况下以及存在于与 C 运行时库调试版本关联的代码中时才会计算传递给它们的表达式。

要求

例程 必需的标头
%> <assert.h>

_assert 函数的签名在标头文件中不可用。 _wassert 函数的签名只有在未定义 NDEBUG 宏时才可用。

示例

在此程序中, analyze_string 函数使用 assert 宏来测试与字符串和长度相关的一些条件。 如果任意条件失败,则程序将打印指示失败原因的消息。

// crt_assert.c
// compile by using: cl /W4 crt_assert.c
#include <stdio.h>
#include <assert.h>
#include <string.h>

void analyze_string( char *string );   // Prototype

int main( void )
{
   char  test1[] = "abc", *test2 = NULL, test3[] = "";

   printf ( "Analyzing string '%s'\n", test1 ); fflush( stdout );
   analyze_string( test1 );
   printf ( "Analyzing string '%s'\n", test2 ); fflush( stdout );
   analyze_string( test2 );
   printf ( "Analyzing string '%s'\n", test3 ); fflush( stdout );
   analyze_string( test3 );
}

// Tests a string to see if it is NULL,
// empty, or longer than 0 characters.
void analyze_string( char * string )
{
   assert( string != NULL );        // Cannot be NULL
   assert( *string != '\0' );       // Cannot be empty
   assert( strlen( string ) > 2 );  // Length must exceed 2
}

该程序会生成以下输出:

Analyzing string 'abc'
Analyzing string '(null)'
Assertion failed: string != NULL, file crt_assert.c, line 25

断言失败后,可能会看到一个包含类似以下内容的消息框(具体取决于操作系统和运行时库的版本):

A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.

如果已安装调试器,请选择“调试” 按钮以启动调试器,或选择“关闭程序” 以退出。

另请参阅

错误处理
进程和环境控制
abort
raise
signal
_ASSERT_ASSERTE_ASSERT_EXPR
_DEBUG