Understanding assert in C/C++

Filed Under: C Programming
Assert C

In this article, we’ll take a look at using the concept of assertions, using the assert in C/C++.

This is not very hard to understand, so let’s get started!

We’ll first look at what we mean by an assertion, and then look at how we can use it in our C programs to debug effectively!


What is an assertion?

An assertion is a specification that verifies that a program satisfies certain conditions at particular points, during its execution (run-time condition checks).

For computer programs, there are primarily three types of assertions checks:

  • Precondition Assertion -> Condition satisfied before main body execution
  • Post-condition Assertion -> Condition satisfied after main body execution
  • Invariant Assertion -> Condition satisfied after every repetitive region of a function (like a loop)

Now that we know what an assertion is, let’s look at doing this in a C program.


Using assertions in C programs

In C, we use the assert macro to define an assertion statement. This is there in the <assert.h> header file.

To define an assertion, we can write something like this:

#include <assert.h>

assert (condition);

Here, condition must be boolean. For example, the below is an example of an assertion:

int i=0;
assert (i >= 0);

The above assertion holds true, since 0>=0. Therefore, during execution, our program continues normally.

If the assert condition holds false, it will produce an error, and our program will stop executing, with suitable error messages.

int i = 0;
// This is false
assert (i > 0);

Now that we’ve covered the basics, let’s look at using assertions in a for loop.

This not only ensures that we want the program to do what we want, but also structures code logically, so that it is easy to read.


An example – Using assert in a loop

Consider the below code, that simply adds integers within a given range. We want to ensure that our final result is always positive, and does not overflow.

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

int loop_function(int a, int b) {
    // Precondition assertion (a <= b)
    assert (a <= b);
    int result = 0;
    for (int i=a; i<=b; i++) {
        // Invariant assertion
        // The cummulative result must always be positive
        // Sometimes, the result may overflow and give a negative
        // integer. In that case, this assertion will fail
        assert (result >= 0);
        result += i;
    }
    // Postcondition assertion
    // Again, the net result must be positive
    // So if result = 0, this condition will fail
    assert (result > 0);
    return result;
}

int main() {
    int a = 3;
    int b = 10;
    printf("loop_function on %d and %d gives %d\n", a, b, loop_function(a, b));

    int c = INT_MAX - 3;
    int d = INT_MAX;
    // Here, in case of c and d, the result will overflow. The invariant assertion will be false!
    printf("loop_function on %d and %d gives %d\n", c, d, loop_function(c, d));

    return 0;
}

Output

loop_function on 3 and 10 gives 52
assert_loop: assert_loop.c:14: loop_function: Assertion `result >= 0' failed.
[1]    337 abort (core dumped)  ./assert_loop

If the value of our result is too high (beyond the integer size), then the result will overflow and become negative!

Our second set of input does this, and hence the loop invariant assertion will fail!

So our program will halt there itself. This ensures that we can detect any design flaw in our program, and handle such inputs accordingly.


Conclusion

In this article, we learned how we could check for assertions, using the assert macro in C/C++. For similar articles on C, do look at our tutorial section on C programming.

References


Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages