ndato.com
Menu
Links
Inheritance in C
Created: 2026-05-01
Tags: C , Patterns

Look what they need to mimic a fraction of our power.

General Idea

In this article, I'll show how to create a generic structure and then implement more specific structures. This way, you can use the generic structure and the generic functions while the specific structures and functions are hidden.

I know, just use an OOP language! Anyway, in C you can mimic some kind of base-generic-class and derived-specific-classes. This won't have all the features of an OOP language, but enough to have more abstraction in C.

As an example, in a video game you may want to have a generic structure+functions for NPCs, but different kind of specific NPCs, the engine would use the generic NPC functions without knowing (nor caring) what specific NPC it is. Another example could be if you want to handle different brands or models of a hardware device, you may want to have a generic structure+functions to use those devices without worrying about the specific API for each particular device.

To do this, you need 4 things:

  • A generic structure, with function pointers that will point to the specific functions
  • Generic functions to operate on the generic structure and call the function pointers
  • The specific structures
  • The specific functions
  • Functions to create each specific structure, but returning the generic structure

Example

In this example we'll have the generic npc structure and a seller structure which is an specific NPC.

/* The npc/seller.h file */

#include "npc.h"

struct npc *seller_create(/*...*/);
int seller_move(npc_seller *seller, int x, int y);
/* The npc/seller.c file */

struct npc_seller {
    struct npc *npc;
    /* where the shop is */
    location shop;
    int nstock;
    /* items for sale */
    items *sock;
    /*...*/
};

int seller_move(npc_seller *seller, int x, int y)
{
    /* keep this NPC inside its shop */
    if (is_outside(seller->shop, x, y)) {
        return -1;
    }
    /*...*/
}

static void seller_free(npc_seller **seller)
{
    if (seller != NULL) {
        free(*seller);
        *seller = NULL;
    }
}

struct npc *seller_create(/*...*/)
{
    struct npc *npc = calloc(1, sizeof(struct npc));
    struct npc_seller *npc_seller = calloc(1, sizeof(struct npc_seller));
    npc->move = seller_move;
    npc->free_private = seller_free;
    npc->private = npc_seller;
    npc_seller->npc = npc;
    /* fill npc_seller */

    return npc;
}
/* The npc/npc.h file */

typedef int (*_npc_move)(void *private, int x, int y);
typedef int (*_npc_set_name)(void *private, const char *name);
typedef void (*_npc_free_private)(void *private);

struct npc {
    char name[1024];
    _npc_move move;
    _npc_set_name set_name;
    _npc_free_private free_private;
    void *private;
};

void npc_set_name(struct npc *npc, const char *name);
int npc_move(struct npc *npc, int x, int y);
void npc_free(struct npc **npc);
/* The npc/npc.c file */

/* This function sets the public name, but also calls the private function */
void npc_set_name(struct npc *npc, const char *name)
{
    if (npc != NULL) {
        strncpy(npc->name, name, sizeof(npc->name - 1));
        if (npc->set_name != NULL) {
            npc->set_name(npc->private, name);
        }
    }
}

/* This function only calls the private function */
int npc_move(struct npc *npc, int x, int y)
{
    if (npc != NULL && npc->move != NULL) {
        return npc->move(npc->private, x, y);
    }
    return -1;
}

void npc_free(struct npc **npc)
{
    if (npc != NULL) {
        if (npc->free_private != NULL) {
            npc->free_private(&(*npc)->private);
        }
        free(*npc);
        *npc = NULL;
    }
}
/* The main.c file */

#include "npc/npc.h"
#include "npc/npc_seller.h"

struct npc *npc = seller_create();
npc_move(npc, 3, 4);
npc_free(&npc);

The generic (base) structure

This generic structure would be like the interface or base class in OOP. The structure should have:

  • Function pointers for each generic function that the derived structures can implement or override. It could be that not all functions are implemented by all derived structures. Those function pointers would be like the methods that will be implemented or extended by subclasses
  • Elements that are generic for all, or almost all, specific (derived) structures. Those would be like the properties of the base class
  • A void * pointer that will hold the pointer to the specific (derived) structure

The generic structure could be opaque or public. I'm usually prone to use opaque structures. It could be a good idea to have a function to create the generic structure, even if the generic structure is public.

The generic functions

The generic functions must receive the pointer to the generic structure, and then have different behaviors:

  • Only operate on the generic structure
  • Only call the specific function
  • Operate on the generic structure but also call the specific function. This isn't how OOP usually works, if you have a derived class and call a method, it will call the derived class' method if it has one. However, you can do whatever you want.

For instance, if the generic structure is an NPC that the player can talk to, there could be a generic function to talk and it would respond with random responses, and some special NPCs could have their own function with particular responses. In this case, the generic function can check if there is a pointer to the specific function and call it, otherwise reply with random phrases.

The specific (derived) structure

This structure would be like the derived class that "inherits" the base class. This should have:

  • The specific elements for this structure
  • A pointer to the generic (base) structure

We can continue deriving structures if we mix the generic (base) structure ideas and the specific (derived) structure ideas. In that case, we would add function pointers and a void * pointer.

The specific functions

The specific functions must receive a pointer to the structure, it could be the specific or the generic structure. However, I think it's better to receive the specific structure. If the function needs to operate on the generic structure, it can use the pointer to it.

Also, this specific function may want to call the generic function.

Considerations

This isn't OOP. If you need OOP, use an OOP language.

There are some examples of this patter, if I understand correctly FFmpeg and the Linux kernel use this, maybe their own way of doing it but both have an abstraction with generic and specific structures and functions.

There are some decisions you can make. Should the specific function receive the generic o the specific structure? Should it be any way to directly use the specific structure and it's functions? Will the generic function do anything else apart from calling the specific function?