Error handling implementation on C static libraries

Viewed 41

I am implementing a simple static library on C, and I have some basic questions regarding the implementation of error handling.

Lets say for the sake of the example, that my library supports a basic linked list which uses Node structure:

typedef struct Node
{
    struct Node* next;
    struct Node* prev;
    int* data;

}Node;


typedef struct LinkedList
{
    Node* head;
    Node* tail;


}LinkedList;

And let's say, as a part of the interface that I'm providing - I'm giving an implementation for a function that inserts a new Node as the LinkedList head

void insertHead(LinkedList* LinkedList, Node* node)
{
    if(LinkedList == NULL || node == NULL)
    {
        // How to implement?
    }
}

I want to catch the most basic error for example - the user of my library tries to enter a NULL pointer. I know that using stderr or printing errors is not a good idea, and also - using asserts is not a good idea.

I somewhat understand that I need to build my own "error - catching mechanism" using a global variable that holds error codes, and converts into strings (Like enums maybe?).

However - I have no idea how to implement such mechanism, how would the user of my library encounter the error itself? the interface itself (the .lib file has only method declerations and such, and the .c file has the implementation) - so after linkage and compilation and such, how would the user get to "see" the errors that I'm providing?

I would love to get a brief example on how to handle user input errors, sorry for being a bit unclear - I am just confused.

1 Answers

I know that using stderr or printing errors is not a good idea, and also - using asserts is not a good idea.

You are right, both would be very bad in a library.

I somewhat understand that I need to build my own "error - catching mechanism" using a global varibale that holds error codes, and converts into strings (Like enums maybe?).

No need for global variables, that is a bad idea. Providing a human/English-readable string equivalent is not too bad, but not really needed. Leave that to the application (what if they need to localize the string?).

how would the user of my library encounter the error itself?

Libraries usually provide whatever is needed in one or more header files that the user of the library #includes.


The easiest way is to have your functions return an error code:

Error insertHead(LinkedList* LinkedList, Node* node)
{
    if(LinkedList == NULL || node == NULL)
    {
        return LINKEDLIST_ERROR_INVALID_ARGUMENT;
    }
}

Here Error can be just an integer and LINKEDLIST_ERROR_INVALID_ARGUMENT a #define. Another option is using an enum. These definitions would be in the header file you give to users of your library.

Your callers will only need to do:

#include <yourlibrary.h>

// ...
{
    if (insertHead(...) != ERROR_OK)
        // whatever they need to do with the error
}
Related