3

C语言中的assert有什么用?怎样在release版本中关闭它?

 3 years ago
source link: https://blog.popkx.com/c%E8%AF%AD%E8%A8%80%E4%B8%AD%E7%9A%84assert%E6%9C%89%E4%BB%80%E4%B9%88%E7%94%A8-%E6%80%8E%E6%A0%B7%E5%9C%A8release%E7%89%88%E6%9C%AC%E4%B8%AD%E5%85%B3%E9%97%AD%E5%AE%83/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C语言中的assert有什么用?怎样在release版本中关闭它?

发表于 2019-09-04 08:09:56   |   已被 访问: 462 次   |   分类于:   C语言   |   暂无评论

相信不少初学者在阅读一些开源的C语言项目时,都会看到 assert 关键字,那么它有什么用呢?

assert 关键字,什么时候使用它?

C语言中的 assert() 方法可以诊断程序 bug,使用之前应该包含 <assert.h> 头文件,它的C语言原型如下,请看:

void assert(int expression);

参数 expression 可以是任意C语言表达式。如果表达式的计算结果为真,assert() 不执行任何操作,反之,如果表达式的计算结果为假,assert() 将在 stderr 上显示错误信息并且终止程序运行。

assert() 一般用于跟踪C语言程序的运行时(与编译时不同)错误,一般这样的错误不是语法错误,所以能够编译通过,但是最终得到的C语言程序在执行时,可能会给出不预期的错误结果。

例如,某段分析财务信息的C语言程序出错了,可能是因为程序中的利率变量 interest_rate 为负导致的,利率是不可能为负的,所以在这样的一段C语言程序中,可以添加如下语句:

assert(interest_rate>=0);

这样一旦出现利率为负的情况,assert() 将(以异常方式)终止程序,并给出错误信息,这样一来,我们就可以根据错误信息排查代码了。例如下面这段C语言程序:

#include <stdio.h>
#include <assert.h>

int main()
{
    double interest_rate = -1;
    assert(interest_rate>=0);

    printf("won't be here\n");

    return 0;
}
458efe26a8384269acbfbce0d1c13acc.png

编译并执行这段C语言代码,得到如下输出:
# gcc t.c
# ./a.out 
a.out: t.c:7: main: Assertion `interest_rate>=0' failed.
Aborted

显然,当 interest_rate 为负数时,assert(interest_rate>=0); 将提前(以异常方式)终止程序运行,并给出错误的原因。与此同时,后续的C语言代码将不再有执行机会。

C语言中的 assert() 还有个方便点在于,程序员一旦开发程序完毕,可以在 release 版本程序中关闭 assert() 宏,此时 assert() 宏将不再提供功能,它在程序中的作用等同于一个空格。这一点可以直接查看 <assert.h> 头文件:

fff7d178ad24133afcc4c4e92bd47bb9.png

显然,通过 NDEBUG 宏就能控制 assert() 方法的开关了。下面是一个例子:
#include <stdio.h>

#define NDEBUG
#include <assert.h>

int main()
{
    double interest_rate = -1;
    assert(interest_rate>=0);

    printf("won't be here\n");

    return 0;
}
72f2b697593ba0e58e11b341e56d895d.png

编译并执行这段C语言代码,可以得到如下输出:
# gcc t.c
# ./a.out 
won't be here

可见,assert() 被关闭了。另外,如果 assert() 失败时,添加一些附加错误提示信息,可以使用“短路表达式”(可参考我之前的文章)的技巧:

#include <stdio.h>
#include <assert.h>

int main()
{
    double interest_rate = -1;
    assert(interest_rate>=0 && "interest rate cannot be negtive!" );

    printf("won't be here\n");

    return 0;
}

字符串"interest rate cannot be negtive!"必定为真,因此决定 assert() 是否失败的因素仍然在于 interest_rate>=0 本身,编译并执行上述C语言代码,得到如下输出:

# gcc t.c
# ./a.out 
a.out: t.c:7: main: Assertion `interest_rate>=0 && "interest rate cannot be negtive!"' failed.
Aborted

本节主要讨论了C语言程序开发中 assert() 宏的使用,它可以在程序开发阶段,帮助程序员定位到一些本不应该发生的情况。更加方便的是,一旦程序开发完毕,程序员可以简单的通过 NDEBUG 宏关闭 assert() 的功能,此时它就等同于一个空格,不会为程序带来任何性能损失。

阅读更多:   C语言


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK