Я пишу приложение в C (gcc), которое делает много сравнения строк. Всегда одна неизвестная/динамическая строка с длинным списком константных строк времени компиляции. Итак, я решил, что я использую динамическую строку и сравниваю полученный хеш с предварительно вычисленными хэшами константных строк.Расширение макроса GCC для вызова другого макроса
Для этого у меня есть хэш-алгоритм в функции (для динамических строк выполнения) и как макрос, так что gcc оценивает хэш во время компиляции.
Я получил это:
#define HASH_CALC(h, s) ((h) * 33 + *(s))
#define HASH_CALC1(s) (HASH_CALC(hash_calc_start, s))
#define HASH_CALC2(s) (HASH_CALC(HASH_CALC1(s), s + 1))
#define HASH_CALC3(s) (HASH_CALC(HASH_CALC2(s), s + 2))
#define HASH_CALC4(s) (HASH_CALC(HASH_CALC3(s), s + 3))
#define HASH_CALC5(s) (HASH_CALC(HASH_CALC4(s), s + 4))
//--> cut ... goes till HASH_CALC32
static const unsigned long hash_calc_start = 5381;
unsigned long hash_str (const char* c);
void func() {
//This string is not constant ... just in this case to show something
char dynStr = "foo";
unsigned long dynHash = hash_str (dynStr);
//gcc produces a cmp with a constant number as foo is hashed during compile-time
if (dynHash == HASH_CALC3("foo")) {
}
}
Теперь на вопрос:
Можно ли создать макрос, который расширяется до HASH_CALCX (ов), где X является длина постоянной строки передается в макрос?
//Expands to HASH_CALC3("foo")
if (dynHash == HASH_CALCX("foo")) {
}
//Expands to HASH_CALC6("foobar")
if (dynHash == HASH_CALCX("foobar")) {
}
Я пробовал это, но он не работает.
#define HASH_STRLEN(x) (sizeof(x)/sizeof(x[0])-1)
#define HASH_MERGE(x,y) x ## y
#define HASH_MERGE2(x,y) HASH_MERGE(x,y)
#define HASH_CALCX(s) (HASH_MERGE2(HASH_CALC, HASH_STRLEN(s))(s))
Спасибо!
Не требуется. 'strlen' отлично работает для строковых констант, возвращая константу compiletime. – Damon
@Damon Well ... #define HASH_CALCX (s) (HASH_MERGE2 (HASH_CALC, strlen (s)) (ы)) не работает, так как strlen ("") не расширяется. – Xatian
Как определяется 'hash_calc_start'? '#define hash_calc_start 0'? – ericbn