Chris
Chris

Reputation: 163

C Macros function definition syntax question

I've been looking through a program called hickit, and at one point (count.c, function starts at line 105), and they call a macros function (kavl_insert) from the Klib library as follows:

static void hk_count_nei2_core(int32_t n_pairs, struct cnt_nei2_aux *a, int r1, int r2)
{
    struct cnt_nei2_aux *root = 0;
    int32_t i, j, left;
    unsigned cl;
    left = 0;
    kavl_insert(nei2, &root, &a[0], 0);
...

Looking at the Klib library (more specifically, in kavl.h), this function (I think) is defined as follows:

#define __KAVL_INSERT(suf, __scope, __type, __head, __cmp) \
    __scope __type *kavl_insert_##suf(__type **root_, __type *x, unsigned *cnt_) { \

Later on in the kavl.h file there is this standalone line (line 322):

#define kavl_insert(suf, proot, x, cnt) kavl_insert_##suf(proot, x, cnt)

I don't have much technical knowledge with C (just learned parts as they were relevant), and I'm wondering how this works. The casing is different, and there is the "__" precursor in the #define line. How does this work?

Upvotes: 1

Views: 98

Answers (1)

vgru
vgru

Reputation: 51214

The first __KAVL_INSERT macro is used to declare functions which all start with the same prefix (kavl_insert_) and end with the specified suffix (parameter suf).

So, when you see this:

__KAVL_INSERT(foo, static, int, null, null)

preprocessor will replace it with a function with the appropriate name, scope, and parameter types:

static int *kavl_insert_foo(int **root_, int *x, unsigned *cnt_) { \
    /* actual function body ... */ \
    /* with lots of trailing backshashes ... */ \
    /* because it's the only way to create ... */ \
    /* a multiline macro in C */ \
}

The lowercase kavl_insert macro, on the other hand:

kavl_insert(foo, &something, &whatever, 0);

simply expands to the actual function call, i.e. it's equivalent to calling the function defined above:

kavl_insert_foo(&something, &whatever, 0);

The idea behind this kind of macros is usually to create a generic type-safe data structure in C, using the preprocessor, like the klib library of various generic data structures.

Upvotes: 1

Related Questions