什么是“断言”?功能?

发布于 2024-08-07 18:41:23 字数 58 浏览 5 评论 0原文

我一直在研究 OpenCV 教程并遇到了 assert 函数;它有什么作用?

I've been studying OpenCV tutorials and came across the assert function; what does it do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

忆沫 2024-08-14 18:41:23

如果断言的参数为假,则断言将终止程序(通常带有一条引用断言语句的消息)。它通常在调试过程中使用,以便在发生意外情况时使程序失败得更明显。

例如:

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));

当您进行发布(非调试)构建时,您还可以消除评估 的开销通过定义 NDEBUG 宏来断言 语句,通常使用编译器开关。由此推论,您的程序永远不应该依赖于断言宏的运行。

// 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 will terminate the program (usually with a message quoting the assert statement) if its argument turns out to be false. It's commonly used during debugging to make the program fail more obviously if an unexpected condition occurs.

For example:

assert(length >= 0);  // die if length is negative.

You can also add a more informative message to be displayed if it fails like so:

assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");

Or else like this:

assert(("Length can't possibly be negative! Tell jsmith", length >= 0));

When you're doing a release (non-debug) build, you can also remove the overhead of evaluating assert statements by defining the NDEBUG macro, usually with a compiler switch. The corollary of this is that your program should never rely on the assert macro running.

// 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);

From the combination of the program calling abort() and not being guaranteed to do anything, asserts should only be used to test things that the developer has assumed rather than, for example, the user entering a number rather than a letter (which should be handled by other means).

樱桃奶球 2024-08-14 18:41:23

assert 计算机语句类似于英语中的ma​​kesure 语句。

The assert computer statement is analogous to the statement make sure in English.

再可℃爱ぅ一点好了 2024-08-14 18:41:23

看一下

C++ 中的assert() 示例程序

许多编译器提供了一个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

Take a look at

assert() example program in C++

Many compilers offer an assert()
macro. The assert() macro returns TRUE
if its parameter evaluates TRUE and
takes some kind of action if it
evaluates FALSE. Many compilers will
abort the program on an assert() that
fails; others will throw an exception

One powerful feature of the assert()
macro is that the preprocessor
collapses it into no code at all if
DEBUG is not defined. It is a great
help during development, and when the
final product ships there is no
performance penalty nor increase in
the size of the executable version of
the program.

Eg

#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
玩心态 2024-08-14 18:41:23

assert() 函数可以诊断程序错误。在 C 中,它在 中定义,在 C++ 中,它在 中定义。它的原型是

void assert(int expression);

参数表达式可以是您想要测试的任何内容——变量或任何 C 表达式。如果表达式的计算结果为 TRUE,则assert() 不执行任何操作。如果表达式的计算结果为 FALSE,assert() 将在 stderr 上显示错误消息并中止程序执行。

如何使用assert()?它最常用于追踪程序错误(与编译错误不同)。错误不会阻止程序编译,但会导致程序给出不正确的结果或运行不正确(例如锁定)。例如,您正在编写的财务分析程序有时可能会给出错误的答案。您怀疑问题是由变量interest_rate 取负值引起的,而这种情况永远不应该发生。要检查这一点,请放置语句

assert(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

错误消息:
程序异常终止

您的错误消息可能会有所不同,具体取决于您的系统和编译器,但总体思路是相同的。

The assert() function can diagnose program bugs. In C, it is defined in <assert.h>, and in C++ it is defined in <cassert>. Its prototype is

void assert(int expression);

The argument expression can be anything you want to test--a variable or any C expression. If expression evaluates to TRUE, assert() does nothing. If expression evaluates to FALSE, assert() displays an error message on stderr and aborts program execution.

How do you use assert()? It is most frequently used to track down program bugs (which are distinct from compilation errors). A bug doesn't prevent a program from compiling, but it causes it to give incorrect results or to run improperly (locking up, for example). For instance, a financial-analysis program you're writing might occasionally give incorrect answers. You suspect that the problem is caused by the variable interest_rate taking on a negative value, which should never happen. To check this, place the statement

assert(interest_rate >= 0);
at locations in the program where interest_rate is used. If the variable ever does become negative, the assert() macro alerts you. You can then examine the relevant code to locate the cause of the problem.

To see how assert() works, run the sample program below. If you enter a nonzero value, the program displays the value and terminates normally. If you enter zero, the assert() macro forces abnormal program termination. The exact error message you see will depend on your compiler, but here's a typical example:

Assertion failed: x, file list19_3.c, line 13
Note that, in order for assert() to work, your program must be compiled in debug mode. Refer to your compiler documentation for information on enabling debug mode (as explained in a moment). When you later compile the final version in release mode, the assert() macros are disabled.

 int x;

 printf("\nEnter an integer value: ");
 scanf("%d", &x);

 assert(x >= 0);

 printf("You entered %d.\n", x);
 return(0);

Enter an integer value: 10

You entered 10.

Enter an integer value: -1

Error Message:
Abnormal program termination

Your error message might differ, depending on your system and compiler, but the general idea is the same.

凹づ凸ル 2024-08-14 18:41:23

对于大多数编译器来说,“引发异常”和“停止执行”之类的东西可能是正确的,但并非适用于所有编译器。 (顺便说一句,是否存在真正引发异常的断言语句?)

这是 c6x 和其他 TI 编译器使用的断言的一个有趣的、略有不同的含义:在看到某些断言语句时,这些编译器使用该语句中的信息来执行某些优化。邪恶。

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;
}

这告诉反编译器数组在 32 位边界上对齐,因此编译器可以生成针对这种对齐方式的特定指令。

Stuff like 'raises exception' and 'halts execution' might be true for most compilers, but not for all. (BTW, are there assert statements that really throw exceptions?)

Here's an interesting, slightly different meaning of assert used by c6x and other TI compilers: upon seeing certain assert statements, these compilers use the information in that statement to perform certain optimizations. Wicked.

Example in 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;
}

This tells de compiler the arrays are aligned on 32-bits boundaries, so the compiler can generate specific instructions made for that kind of alignment.

悲凉≈ 2024-08-14 18:41:23

C++11 N3337 标准草案

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

19.3 断言

1 标头(表 42)中所述,提供了用于记录 C++ 程序断言的宏
以及禁用断言检查的机制。

2 内容与标准C库头文件相同。

C99 N1256标准草案

http >

7.2 诊断

1 标头 定义断言宏并引用另一个宏 NDEBUG,该宏未由 定义;。如果 NDEBUG 被定义为宏名称
指向源文件中的位置包含在内,断言宏简单地定义为

 #define 断言(忽略) ((void)0)

每次断言宏都会根据 NDEBUG 的当前状态重新定义
包含

2.
断言宏应作为宏实现,而不是作为实际函数。如果
为了访问实际函数,宏定义被抑制,行为是
未定义。

7.2.1 程序诊断

7.2.1.1 断言宏

剧情简介

1.

#include ;
void断言(标量表达式);

描述

2
断言宏将诊断测试放入程序中;它扩展为 void 表达式。
执行时,if 表达式(应具有标量类型)为 false(即
比较等于 0),断言宏写入有关特定调用的信息
失败(包括参数文本、源文件名、源行
数字和封闭函数的名称 - 后者分别是值
预处理宏 __FILE____LINE__ 以及标识符
__func__) 以实现定义的格式处理标准错误流。 165) 它
然后调用中止函数。

退货

3
断言宏不返回任何值。

C++11 N3337 standard draft

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

19.3 Assertions

1 The header <cassert>, described in (Table 42), provides a macro for documenting C ++ program assertions
and a mechanism for disabling the assertion checks.

2 The contents are the same as the Standard C library header <assert.h>.

C99 N1256 standard draft

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

7.2 Diagnostics <assert.h>

1 The header <assert.h> defines the assert macro and refers to another macro, NDEBUG which is not defined by <assert.h>. If NDEBUG is defined as a macro name at the
point in the source file where <assert.h> is included, the assert macro is defined simply as

 #define assert(ignore) ((void)0)

The assert macro is redefined according to the current state of NDEBUG each time that
<assert.h> is included.

2.
The assert macro shall be implemented as a macro, not as an actual function. If the
macro definition is suppressed in order to access an actual function, the behavior is
undefined.

7.2.1 Program diagnostics

7.2.1.1 The assert macro

Synopsis

1.

#include <assert.h>
void assert(scalar expression);

Description

2
The assert macro puts diagnostic tests into programs; it expands to a void expression.
When it is executed, if expression (which shall have a scalar type) is false (that is,
compares equal to 0), the assert macro writes information about the particular call that
failed (including the text of the argument, the name of the source file, the source line
number, and the name of the enclosing function — the latter are respectively the values of
the preprocessing macros __FILE__ and __LINE__ and of the identifier
__func__) on the standard error stream in an implementation-defined format. 165) It
then calls the abort function.

Returns

3
The assert macro returns no value.

夜深人未静 2024-08-14 18:41:23

使用assert()函数而不是普通的if else有三个主要原因,并且printf

  1. assert()函数主要用于调试阶段,每次要测试时都用printf语句编写if else是很繁琐的一个条件甚至可能不会出现在最终的代码中。

  2. 在大型软件部署中,assert 非常方便,您可以使用在链接assert() 函数的头文件之前定义的 NDEBUG 宏让编译器忽略断言语句。

  3. 当您设计一个函数或某些代码并想要了解什么限制代码将工作或不工作时,assert() 会很方便,并最终包含一个 if else 来评估它,基本上是在假设的情况下进行评估。

There are three main reasons for using the assert() function over the normal if else and printf

  1. assert() function is mainly used in the debugging phase, it is tedious to write if else with a printf statement everytime you want to test a condition which might not even make its way in the final code.

  2. In large software deployments , assert comes very handy where you can make the compiler ignore the assert statements using the NDEBUG macro defined before linking the header file for assert() function.

  3. assert() comes handy when you are designing a function or some code and want to get an idea as to what limits the code will and not work and finally include an if else for evaluating it basically playing with assumptions.

月牙弯弯 2024-08-14 18:41:23

如果它计算的值为 false,则该函数将停止程序执行。通常它被宏包围,以便在使用发布设置编译时不会将其编译到生成的二进制文件中。

它旨在用于测试您所做的假设。例如:

void strcpy(char* dest, char* src){
    //pointers shouldn't be null
    assert(dest!=null);
    assert(src!=null);

    //copy string
    while(*dest++ = *src++);
}

您想要的理想情况是您可以在程序中犯错误,例如调用带有无效参数的函数,并且在出现段错误(或无法按预期工作)之前命中断言

It is a function that will halt program execution if the value it has evaluated is false. Usually it is surrounded by a macro so that it is not compiled into the resultant binary when compiled with release settings.

It is designed to be used for testing the assumptions you have made. For example:

void strcpy(char* dest, char* src){
    //pointers shouldn't be null
    assert(dest!=null);
    assert(src!=null);

    //copy string
    while(*dest++ = *src++);
}

The ideal you want is that you can make an error in your program, like calling a function with invalid arguments, and you hit an assert before it segfaults (or fails to work as expected)

薄暮涼年 2024-08-14 18:41:23

此外,您还可以用它来检查动态分配是否成功。

代码示例:

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);
}

In addition, you can use it to check if the dynamic allocation was successful.

Code example:

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.

Similar to:

if (p == NULL) {
    cout << "dynamic allocation failed" << endl;
    exit(1);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文