Using Assert.h in C


Reading time: 25 minutes | Coding time: 5 minutes

This article will talk about the assert.h header file that comes with the standard C library. The C language heavily depends on header files, these files are like (small) libraries. To keep C code as lean as possible you have to import header files before you get any usefull functionality at your deposal. In this article we'll talk about one of those header files, namely the assert.h header file. First we'll look at the purpose of this file, second we'll go over code examples and in the third part we'll dive a little deeper into the details of this header file and tips on how to use it.

assert-pigeons

Purpose of assert.h

The purpose of assert.h is to test assumptions. In C there are a few frameworks to test code, but those frameworks aren't as easy as for example JUnit in Java. Assert.h is a very simple way to write a few quick tests. If the assumption you make about the code is correct it continues without disruption. If the assumption isn't correct it prints a diagnostic message. That message can look like this:

Assertion failed: (x == y), function main, file assert-demo.c, line 8.
Abort trap: 6

Syntax

Before we can use assert we have to import it first, like so:

#include <assert.h>

After that you can use assert like this:

void assert(int expression)

Do you want to see it in action? Let's assume that a = 1 when we assign 1 to a.

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

int main() {
    int a = 1;
    assert(a == 1);
    
    printf("You assumped correctly! A = 1");
    return 0;
}

The above example will return the following:

You assumped correctly! A = 1

Because a is indeed 1. What do you think happens when we assign a different value to a? Let's change the code to te following:

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

int main() {
    int a = 5;
    assert(a == 1);
    
    printf("You assumped correctly! A = 1");
    return 0;
}

Now we have a different result.

Assertion failed: (a == 1), function main, file assert-demo.c, line 6.
Abort trap: 6

You can clearly see the assert worked correctly, it aborted the code and it printed on which assertion it failed which is nice when you have multiple assert calls in your code. Maybe you also spotted something else, what do you see on the last line of the error message? We'll talk about that next.

Abort

In the last line of the error message you can see 'Abort trap: 6'. In short this means the code aborted, which in turn means that the code stopped right there, anything that comes after that assert will be skipped. The precise message might be slightly different, 'Abort trap: 6' is UNIX specific.

Example

The next example reads a file and we add an assertion to see if the file gets read correctly:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
 
int main(void)
{
    FILE *fp;
 
    /* open file */
    fp = fopen("hello.txt", "r");
 
    /* assert if file opened successfully */
    assert(fp != NULL);
 
    /* do something with the file */
 
    /* close file */
    fclose(fp);
    return 0;
}

The code either returns:

Assertion failed: (fp != NULL), function main, file readTest.c, line 13.
Abort trap: 6

or it returns nothing and you know the assumption was correct. Try this your self and see what happens. First run it with the hello.txt file present and when that works delete the hello.txt file and run it again. Do you see the error message???

Deep dive

So let's say you practiced with assert calls and used them in your code. Everyting seems fine and you are ready to roll out your code to production, but them you remember somehting. When an assert fails it aborts your whole program! You don't want that to happen. In your production code you don't want asserts just like you don't want your production code to run your unit tests. Luckily there's a fix for that. Of course you can delete all the assert calls, but you don't want to add all of them again when you need to debug the code. That's why you can completely remove assertions at compile time using the preprocessor NODEBUG. It works like this:

#include <stdio.h>
#define NDEBUG 
#include <assert.h> 
  
int main() 
{ 
    int a = 5; 
    assert (a==1); 
    return 0; 
} 

Even though the assert will fail in debug mode, the above program compiles and runs fine.

Question

How would you call assert

Macro
Function
This is actually a macro and not a function, which can be used to add diagnostics in your C program.

Conclusion

To sum it all up, we talked about what assert.h is used for namely to test your assumptions about the code and we talked about a few examples. Now it's your turn to start using it. When you have any question or remakrs, feel free to open the discussin below. If you want a short recap in video format checkout this YouTube video: https://www.youtube.com/watch?v=IcezlC5l7_k