首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事

C++中的断言的用法。ASSERT

发布网友

我来回答

3个回答

热心网友

assert是包含在头文件<cassert>中的宏定义,如下:

#ifdef NDEBUG
#    define assert(condition) ((void)0)
#else
#    define assert(condition) /*implementation defined*/
#endif

由此可见,当NDEBUG已经定义时,assert没有任何作用。反之,condition为零时,assert会终止程序。

通常,debug(调试)模式下不会定义NDEBUG;而release(发布)模式下,会定义NDEBUG。由此可知,assert是用于调试的命令。

一般而言,在编写程序时,我们会假设输入、输出满足一定的条件。由于程序员的疏忽,我们不太可能一次就写对程序。当出现错误时,我们所做的假设可能会不成立。如果我们能将所有假设都用assert进行判断,那么程序出错时,我们能在第一时间发现问题所在。另一方面,我们希望对假设条件的判断不会影响程序的效率。因此,当我们确信程序没有错误时,我们希望assert什么都不做。请看如下示例:

#include <cassert>

template<typename T>
T multiply(T const& a, T const& b) {
    return a * b;
}

template<typename T>
T div(T const& a, T const& b) {
    return a / b;
}

int main() {
    double const a = 1, b = 2;
    assert(multiply(div(a, b), b) == a);

    return 0;
}

其中定义了multiple(乘法),div(除法)操作。表面上,我们并没有什么错误,不过为了保险起见,我们使用了assert进行验证。结果正如我们希望的,没有任何错误。然而,当我们将a, b的类型改为int时,程序出错了(debug模式)。因为,div的定义其实是有问题的(相信楼主能看出来吧^^)。

总之,每当我们对程序有任何假设、期望,都应该将它转化为assert语句写入程序当中。它能帮助我们定位错误的位置,缩短调试时间,百利而无一害。


PS: 需要注意的是assert应该用于处理程序中的逻辑错误,而不是输入错误。因此判断文件打开是否出错,应该使用异常等错误处理机制,而不是assert。

热心网友

假如不写assert,调试的时候问题未必会暴露出来。此时就如问题所描述的,在调试的时候没事,可是到执行的时候出问题了你又没解决机制……


比如说


FILE*fp;
fp=fopen("错误的文件名?!","w+");

不管文件存不存在,代码都会继续往下运行,问题一时半会不会暴露,有的时候说不定这次调试就没看出问题……

如果写成

FILE*fp;
fp=fopen("错误的文件名?!","w+");
assert(fp!=NULL);

在打开文件失败的时候就会立刻发现断言失败,调试中断,要求立刻修改代码,解决问题,这样才能在实际中不会出问题……

追问这样说,ASSERT是针对那些不是完整项目,只是一部分,只能调试检测错误,而不能运行测试的地方?
比较适合多个人合作的时候?
比如我现在就是自己在写个小程序,其实是完全没有必要的喽,可以直接运行一下就知道有没有问题了呗。
毕竟如果fp=NULL的时候,运行的时候肯定会崩溃或者报错。

追答如果fp=NULL的时候,运行的时候肯定会崩溃或者报错


如果代码多,未必执行到这个分支,就未必了。比如这一段代码用于在出现内存耗尽的时候把一部分数据交换到硬盘文件,假如调试的时候内存没有耗尽,根本没用到这个文件,就不会出错。或者用到了,但是是在跟 fopen 相差十万八千里的另一段代码里面用的,这样排查就很不容易


不过技巧、约定都是用于大项目的(也不一定是多个人合作),代码一眼就能看完的情况下,认为完全没有必要大概也没关系

热心网友

把一个表达式传给assert函数 如果表达式不为真就会中断
通常用在定位错误的时候

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com