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

- 254,901
- 44
- 429
- 631

- 3,514
- 7
- 30
- 42
-
22Notice the note from man assert: *"assert() is implemented as a macro; if the expression tested has side-effects, program behavior will be different depending on whether NDEBUG is defined. This may create Heisenbugs which go away when debugging is turned on."* – Johannes Schaub - litb Oct 15 '09 at 10:05
-
1http://www.opengroup.org/onlinepubs/000095399/functions/assert.html – Steve Jessop Oct 15 '09 at 11:48
-
37@S.Lott now people searching google will find this page as one of the top search results, providing a good peer reviewed answer to their question, and promoting Stack Overflow at the same time, so it's a +1 from me! – Matt Grum Jan 30 '13 at 10:43
-
7It's a -1 from me. The top search result should be the _documentation_ that the OP ought to have consulted in the first place. – Lightness Races in Orbit Apr 14 '16 at 13:09
-
11@LightnessRacesinOrbit. Call me lazy, but I prefer to use the excellent condensed, summarized, and explained readings of documentation that knowledgeable SO users like yourself provide. My heartfelt thanks :) – Tyson Hilmer Mar 26 '18 at 12:32
9 Answers
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).

- 30,738
- 21
- 105
- 131

- 127,331
- 53
- 180
- 211
-
55"`assert` usually raises an exception" -- in C++ it does not rise "exception" it calls abort... it is little bit different. – Artyom Oct 15 '09 at 10:55
-
5I don't think this answer is about the same languages as the question is tagged (C and C++). In C and C++, assert does not raise an exception, it has parentheses around its argument, and the `#` character does not introduce a comment. – Steve Jessop Oct 15 '09 at 11:36
-
Here are your options: Make the answer community-wiki and edit your question removing the old stuff, asking others to place the correct information. That way, downvotes won't affect your rep, and people can improve the answer. – Johannes Schaub - litb Oct 17 '09 at 01:27
-
I dont think that your "assert comments" are useful because it will also output filename and line where assert failed. – Zaffy Aug 18 '12 at 22:41
-
3
-
1Currently, in VS 2015, the assert with an error message will not work because it is out of order. It should be `assert("error message", expression)` – Dooskington Oct 14 '16 at 15:37
-
How does the second code segment with the `&& "..."` work? Is the `const char*` casted to a non-zero `int` which is interpreted as `&& true`? Why does this syntax print the error message? What is this wizardry? Is this simply an operator overload? I am confused. – unknown6656 Dec 08 '20 at 01:32
-
1@unknown6656 you seem to be correct in that the "string" (`const char*`) is actually a pointer, and in C, any non-zero expression evaluates to `true`, so it doesn't affect the assertion itself (`x && true` = `x`). The message is then printed, as `assert` prints the expression it evaluates, which includes the string. Thus, the "error message" gets printed. – TheMadHau5 Dec 10 '20 at 07:55
The assert computer statement is analogous to the statement make sure in English.

- 2,167
- 1
- 16
- 8
-
151Well, not quite. “Make sure the light is off” means “check the light and turn it off if it's on,” not “see if the light is off and if not please explode.” I'd say “double-check” is a closer translation. – Luke Maurer Nov 15 '12 at 06:32
-
8@Luke, that illustrates the wonders of the English language, in that the language offers many ways to say the same thing. But consider assert(length > 0). So we can translate that to *"double-check the length is greater than zero"* or *"make sure the length is greater than zero"*. While clearly both options work, I still prefer mine ;) – Blake7 Mar 22 '14 at 04:12
-
4Well, but the other interpretation is “_make_ the length be greater than zero.” So there's a bit more ambiguity. – Luke Maurer Apr 01 '14 at 01:10
-
55
-
Indeed, "make sure" could be interpreted as "check, and if not ok, change". – Erik Bongers Apr 21 '20 at 14:50
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

- 184,426
- 49
- 232
- 263
-
12
-
2What's that "many compilers" about? MSVC and GCC are both standards compliant on this one. Which non-compliant compilers: don't have assert; don't print a message and abort when an assert fails; use DEBUG instead of the proper NDEBUG? – Steve Jessop Oct 15 '09 at 11:43
-
1lmao, of course it's a website called _java-samples_ that gets this so wrong. – underscore_d Jul 11 '16 at 18:43
-
NDEBUG is not recommended to be used. In man assert: "If the macro NDEBUG is defined at the moment
was last included, the macro assert() generates no code, and hence does nothing at all. It is not recommended to define NDEBUG if using assert() to detect error conditions since the software may behave non-deterministically." – Robert Rademacher Aug 26 '22 at 08:38 -
Robert, what your quote from the assert's man page says is NDEBUG should not be defined **if** assert is being used to detect error conditions. However, assert *should not* be used to detect error conditions. – Daniel Sep 15 '22 at 15:53
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.

- 315
- 2
- 12

- 1,121
- 1
- 13
- 17
-
You explained how your sample program works with assert. Not how assert itself works. How does it end the program abnormally ? does it throw some kind of exception? What kind? Does it create a special signal? what signal? Can assertions be "caught" by any kind of C++ try-catch mechanism? – Motti Shneor Sep 14 '16 at 20:06
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.

- 30,738
- 21
- 105
- 131

- 34,664
- 13
- 111
- 163
-
1So what do they do if the assert is false and NDEBUG is not set? If this is the version of assert from
, then the standard requires that it print a message and abort. Obviously the standard doesn't say they aren't allowed to optimise based on the truth of the statement, but to be compliant they still have to abort if it's false. – Steve Jessop Oct 15 '09 at 11:46 -
1
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>
. IfNDEBUG
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.

- 30,738
- 21
- 105
- 131

- 347,512
- 102
- 1,199
- 985
There are three main reasons for using the assert() function over the normal if else and printf
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.
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.
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.

- 160
- 1
- 3
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)

- 54,544
- 15
- 116
- 120
-
-
1Because you shouldn't ever pass a null pointer to strcpy. It is one of those things that Should Not Happen. If a null pointer has been passed it indicates that something at a higher level has messed up. At best you end up having to crash the program further from the problem due to unexpected data values (either dest being incorrect or null). – Yacoby Oct 30 '09 at 22:19
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);
}

- 30,738
- 21
- 105
- 131

- 1
- 3
-
3No. `new` throws an exception on allocation failure unless you specify `nothrow` (which you didn't here). Furthermore, your formatting is weird and `exit` is evil. – Lightness Races in Orbit Apr 14 '16 at 13:09
-
Yes you are right. I forgot to add not. Would love to see how you will use instead of exit – Sadikov Apr 14 '16 at 21:16
-
1@Sadikov Anyone else would handle such an error condition using code that isn't _**completely removed when building in release mode**, thereby leaving your users without protection and at the mercy of undefined behaviour if a precondition is not satisfied and, thanks to this, is never checked and caught_. `assert()` is only for debugging and stamping out things that should never, ever, **never** happen - long before a release build is made. – underscore_d Jul 11 '16 at 18:50