C宏函数定义语法问题

问题描述

我一直在浏览一个名为hickit的程序,并且在某一点(count.c,函数从第105行开始),他们从Klib库中调用函数(kavl_insert),如下所示:

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);
...

看一下Klib库(更具体地说,在kavl.h中),该函数(我认为)的定义如下:

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

稍后在kavl.h文件中,有以下独立行(第322行):

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

我对C没有太多的技术知识(只是学习了相关的部分),我想知道这是如何工作的。大小写不同,并且#define行中有“ __”前体。如何运作?

解决方法

第一个__KAVL_INSERT宏用于声明所有以相同前缀(kavl_insert_)开头并以指定后缀(参数suf)结尾的函数。

因此,当您看到此内容时:

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

预处理器会将其替换为具有适当名称,范围和参数类型的函数:

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 */ \
}

另一方面,小写的kavl_insert宏:

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

仅扩展为实际的函数调用,即等效于调用上面定义的函数:

kavl_insert_foo(&something,0);

这种宏背后的想法通常是使用预处理器(例如,各种通用数据结构的klib库)在C语言中创建通用的类型安全数据结构。