头文件中的完整宏

时间:2014-10-23 08:15:25

标签: c header c-preprocessor

我找到了一个用以下代码定义哈希表的标题:

#ifndef HASH_H
#define HASH_H

#define DEFINE_HASHTABLE(name, type, key, h_list, hashfunc)\
\
struct list * hashtable;\
\
static int hashtable_init (size_t size)\
{\
    unsigned long i;\
    hashtable = (struct list*)malloc(size * sizeof (struct list_head));\
    if (!hashtable)\
        return -1;\
    for (i = 0; i < size; i++)\
        INIT_LIST_HEAD(&hashtable[i]);\
    return 0;\
}\
\
static inline void hashtable_add(type *elem)\
{\
    struct list_head *head = hashtable + hashfunc(elem->key);\
    list_add(&elem->h_list, head);\
}\
\
static inline void hashtable_del(type *elem)\
{\
    list_del(&elem->h_list);\
}\
\
static inline type * hashtable_find(unsigned long key)\
{\
    type *elem;\
    struct list_head *head = hashtable + hashfunc(key);\
\
    list_for_each_entry(elem, head, h_list){\
        if (elem->key == key) \
            return elem; \
    }\
    return NULL;\
}

#endif /* _HASH_H */

我从未见过像这样的头文件。这种方式写头的好处是什么(我的意思是完整的宏)?它是关于通用性还是类似的东西?

1 个答案:

答案 0 :(得分:2)

这是一种尝试确保所有散列函数调用都已授予其inline请求的方法,即在执行散列表操作时减少函数调用的数量。

这只是一次尝试,它不能保证函数将被内联,但通过使它们static至少有机会改进。有关此问题的大量讨论,请参阅this question,特别是@Christoph answer here

请注意,每个C文件只能使用一次,因为没有&#34; unique&#34;部分添加到函数名称。

如果你这样做:

#include "hash.h"

DEFINE_HASHTABLE(foo, /* rest of arguments */);
DEFINE_HASHTABLE(bar, /* another bunch of args */);

您将收到编译错误,因为所有hashtable_函数都将被定义两次。宏编写器可以通过将一组宏添加name到所有定义的内容(变量和函数)来改进这一点。

即。这样:

struct list * hashtable;\
\
static int hashtable_init (size_t size)\

应该成为:

static list *hashtable_ ##name;\
\
static int hashtable_ ##name ##_init(size_t size)\

依此类推(其中name是第一个宏参数,即上面示例用法中的foobar