我正在寫一個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(S),其中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'對於字符串常量來說非常好,它返回一個編譯時常量。 – Damon
@Damon Well ... #define HASH_CALCX(s)(HASH_MERGE2(HASH_CALC,strlen(s))(s))無法正常工作,因爲strlen(「」)不能擴展。 – Xatian
如何定義'hash_calc_start'? '#define hash_calc_start 0'? – ericbn