我一直在研究OpenCV教程,并遇到了该assert
功能。它有什么作用?
我一直在研究OpenCV教程,并遇到了该assert
功能。它有什么作用?
Answers:
assert
如果其参数结果为false,则将终止程序(通常在消息中引用assert语句)。如果发生意外情况,通常在调试过程中使程序更明显地失败。
例如:
assert(length >= 0); // die if length is negative.
如果失败,您还可以添加一条更多信息的消息来显示,如下所示:
assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");
否则像这样:
assert(("Length can't possibly be negative! Tell jsmith", length >= 0));
在进行发布(非调试)构建时,通常还可以使用编译器开关assert
来定义NDEBUG
宏,从而消除评估语句的开销。必然的结果是您的程序永远不应依赖于assert宏的运行。
// BAD
assert(x++);
// GOOD
assert(x);
x++;
// Watch out! Depends on the function:
assert(foo());
// Here's a safer way:
int ret = foo();
assert(ret);
从程序调用abort()的组合,并不能保证做任何事情,断言应仅用于测试开发人员已经假设的事情,而不是例如,用户输入数字而不是字母(应该是通过其他方式处理)。
assert
通常会引发异常”-在C ++中,它不会引发“异常”,它称为中止...这有点不同。
#
字符不会引入注释。
assert("error message", expression)
该断言计算机语句是类似于声明补充一定的英语。
看一眼
许多编译器提供assert()宏。assert()宏如果其参数评估为TRUE,则返回TRUE;如果评估为FALSE,则采取某种措施。许多编译器会在assert()失败的情况下中止程序;其他人会抛出异常
assert()宏的一项强大功能是,如果未定义DEBUG,则预处理器会将其折叠为任何代码。这在开发过程中提供了很大的帮助,并且在最终产品出厂时,不会降低性能,也不会增加程序的可执行版本的大小。
例如
#include <stdio.h>
#include <assert.h>
void analyze (char *, int);
int main(void)
{
char *string = "ABC";
int length = 3;
analyze(string, length);
printf("The string %s is not null or empty, "
"and has length %d \n", string, length);
}
void analyze(char *string, int length)
{
assert(string != NULL); /* cannot be NULL */
assert(*string != '\0'); /* cannot be empty */
assert(length > 0); /* must be positive */
}
/**************** Output should be similar to ******************
The string ABC is not null or empty, and has length 3
assert()函数可以诊断程序错误。在C中,它是在中定义的<assert.h>
;在C ++中,是在中定义的<cassert>
。它的原型是
void assert(int expression);
参数表达式可以是您要测试的任何内容-变量或任何C表达式。如果expression的计算结果为TRUE,则assert()不执行任何操作。如果expression的计算结果为FALSE,则assert()在stderr上显示错误消息,并中止程序执行。
您如何使用assert()?它最常用于跟踪程序错误(与编译错误不同)。错误不会阻止程序编译,但是会导致程序给出错误的结果或运行不正确(例如,锁定)。例如,您正在编写的财务分析程序有时可能会给出错误的答案。您怀疑问题是由变量interest_rate取负值引起的,这种情况永远不会发生。要对此进行检查,请放置以下语句
断言(interest_rate> = 0); 在程序中使用interest_rate的位置。如果变量确实变为负数,则assert()宏会警告您。然后,您可以检查相关代码以找到问题的原因。
要查看assert()的工作方式,请运行下面的示例程序。如果输入非零值,程序将显示该值并正常终止。如果输入零,则assert()宏将强制程序异常终止。您看到的确切错误消息将取决于您的编译器,但这是一个典型示例:
断言失败:x,文件list19_3.c,第13行请注意,为了使assert()工作,必须在调试模式下编译程序。有关启用调试模式的信息,请参阅您的编译器文档(稍后说明)。当您以后在发布模式下编译最终版本时,assert()宏将被禁用。
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
输入一个整数值:10
您输入了10。
输入一个整数值:-1
错误消息:异常程序终止
您的错误消息可能会有所不同,具体取决于您的系统和编译器,但是总体思路是相同的。
对于大多数编译器而言,诸如“引发异常”和“停止执行”之类的东西可能适用,但并非对所有编译器都适用。(顺便说一句,有没有断言确实引发异常?)
这是c6x和其他TI编译器使用的assert的一个有趣的,略有不同的含义:在看到某些assert语句后,这些编译器使用该语句中的信息来执行某些优化。邪恶。
在C中的示例:
int dot_product(short *x, short *y, short z)
{
int sum = 0
int i;
assert( ( (int)(x) & 0x3 ) == 0 );
assert( ( (int)(y) & 0x3 ) == 0 );
for( i = 0 ; i < z ; ++i )
sum += x[ i ] * y[ i ];
return sum;
}
这告诉de编译器数组在32位边界上对齐,因此编译器可以生成针对这种对齐方式的特定指令。
C ++ 11 N3337标准草案
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3断言
1表42中描述的标头<cassert>提供了用于记录C ++程序断言的宏以及用于禁用断言检查的机制。
2内容与标准C库头文件<assert.h>相同。
C99 N1256标准草案
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2诊断<assert.h>
1标头
<assert.h>
定义断言宏,并引用另一个NDEBUG
未由定义的宏<assert.h>
。如果NDEBUG
在源文件中包含<assert.h>的位置将其定义为宏名称,则将assert宏定义为#define assert(ignore) ((void)0)
每次
<assert.h>
包含时,将根据NDEBUG的当前状态重新定义断言宏 。2.断言宏应实现为宏,而不是实际功能。如果取消了宏定义以访问实际功能,则该行为未定义。
7.2.1程序诊断
7.2.1.1断言宏
概要
1。
#include <assert.h> void assert(scalar expression);
描述
2 assert宏将诊断测试放入程序中;它扩展为一个空表达式。执行时,如果expression(应为标量类型)为false(即比较等于0),则assert宏将写入有关失败的特定调用的信息(包括自变量的文本,源文件,源行号和封装函数的名称-后者分别是标准错误流上实现定义格式的预处理宏
__FILE__
和__LINE__
标识符 的值__func__
。165)然后调用中止功能。退货
3 assert宏不返回任何值。
如果该函数评估的值为false,它将停止程序执行。通常,它被一个宏包围,因此使用发行版设置编译时,它不会编译成结果二进制文件。
它旨在用于测试您所做的假设。例如:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
您想要的理想选择是您可以在程序中出错,例如调用带有无效参数的函数,并且在断言错误(或无法按预期工作)之前命中一个断言。
另外,您可以使用它来检查动态分配是否成功。
代码示例:
int ** p;
p = new int * [5]; // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
// array (size 3) of actual int values
}
assert (p); // Check the dynamic allocation.
相似:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
除非您指定nothrow
(在此处未指定),否则分配失败将引发异常。此外,您的格式化很奇怪而且exit
很邪恶。
assert()
仅用于调试和淘汰不应该,永远,永远不会发生的事情-在构建发行版之前很久。