C Callbacks

Jaime LopezJaime Lopez
2 min read

Assume that you have a C function that accepts another function as an argument, mostly known as a callback. This is used to delegate processing data from one function to another, without pre-defining how that other function will work. Ex-post, the developer has the freedom to choose among different implementations of callback functions.

A basic example for a callback function is to delegate displaying a message. Assume that you are a library writer, so you anticipate that your library can be used by a command line application and by another with a graphical user interface. In the first case, a printf call can be enough to display in the console a message generated by your library. However, creating a dialog window to display that message can be required for the GUI application.

An example of callback functions (example.c): iso_time is a function that generates a string with the current time in ISO format. It receives as argument a callback function which is supposed to display that message. Once the current time is generated, the callback function is called to process the message.

#include <stdio.h>
#include <time.h>

void iso_time(void (*callback)(const char *)) {
    time_t now;
    time(&now);
    callback(ctime(&now));
}

void display_naked(const char *message) {
    puts(message);
}

void display_labeled(const char *message) {
    printf("Time: %s", message);
}

int main() {
    iso_time(display_naked);
    iso_time(display_labeled);
    return 0;
}

In the previous example, display_naked and display_labeled are alternatives of callback functions. They just print the message, but display_labeled includes a label before the message. The main function calls iso_time two times, passing as argument display_naked and display_labeled respectively. Compiling and running the program produces an output like it is shown below.

$ gcc -o example example.c
$ ./example
Sat Feb 15 22:23:39 2025

Time: Sat Feb 15 22:23:39 2025

Using callback functions is a valuable technique for modular software development, i.e. one in which different pieces are loosely coupled. Some modules can be easily updated and replaced to support multiple test and use cases. Furthermore, many widely used libraries and applications, like for network communications, gaming, and user interfaces, are supported by callback functions.

0
Subscribe to my newsletter

Read articles from Jaime Lopez directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jaime Lopez
Jaime Lopez