2014-10-23 4 views
1

Я нашел заголовок для определения хэш-таблицу с помощью следующего кода:Полный макрос в файле заголовка

#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 */ 

Я никогда не видел такой файл заголовка это одно. В чем преимущество этого способа написать заголовок (я имею в виду полный макрос)? Это о простоте или подобном?

+2

Что вы не понимаете? Функции, которые генерирует этот макрос при его расширении? Кстати, это довольно плохой дизайн, имеющий глобальную переменную с фиксированным именем. Вероятно, этот код еще не закончен, вы поймали его посередине. –

ответ

2

Это способ, чтобы гарантировать, что все вызовы функций хэш-функции имеют предоставленный им inline запрос, т. Е. Уменьшить количество вызовов функций при выполнении операций хеш-таблицы.

Это просто попытка, она не может гарантировать, что функции будут встроены, но, сделав их static, шанс, по крайней мере, улучшится. См. this question для подробного обсуждения этого вопроса, в частности @Christoph's answer here.

Обратите внимание, что он будет работать только один раз на C-файл, так как нет никакой уникальной части, добавленной к именам функций.

Если вы:

#include "hash.h" 

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

вы получите сообщение об ошибке компиляции, поскольку все hashtable_ функции будут определены два раза. Макро-писатель мог бы улучшить это, добавив name ко всем вещам, определенным (переменные и функции) с помощью набора макросов.

I.e. это:

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

должен стать чем-то вроде:

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

и так далее (где name является первым аргументом макроса, т.е. foo и bar из моего примера использования выше).

+0

... и к названию глобальной переменной ... –

+0

@JensGustedt Правда, спасибо. Я отредактировал для ясности. – unwind

+0

Не могли бы вы рассказать о том, как макрос гарантирует, что запрос 'inline' будет предоставлен? – Cantfindname

Смежные вопросы