I am creating a kernel module. In this module I need to check inputs against some pre-defined strings. In C++ it's possible to create a constexpr function that calculates the hash at compile time. I am looking for a way to do that in C.
Some pseudo code using the Jenkins hash function :
u32 hash(const char *key)
{
u32 hash, i;
size_t len;
len = strlen(key);
for(hash = i = 0; i < len; ++i)
{
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
const u32 myStringList [] = {
hash("hello"),
hash("this is a text"),
hash("good morning")
};
int findString(const char * searchStr) {
u32 h;
int i;
h = hash(searchStr);
for (i = 0; i < sizeof(myStringList)/sizeof(const u32); i++) {
if (h == myStringList[i]) return i;
}
return -1;
}
How to modify it to get work?
I don't think you can, C doesn't have constexpr
or compile-time evaluation. That's why many people turn to the preprocessor (which is less often used in C++), but string processing (as opposed to string "construction") using that isn't very easy.
Sometimes this can be worked around by adding another preprocessing step, perhaps using some higher-level language (I favor Python) to build the required C code.
If that's not an option, then I'd simply initialize the hash table once during startup. If you don't have an explicit init-function (I believe Linux kernel modules do), you can of course use a static flag:
static const char *strings[] = { "hello", "this is a text", "good morning", NULL };
static uint32_t myStringList[(sizeof strings / sizeof *strings) - 1];
void something(const char *string)
{
static bool hash_initialized = false;
if(!hash_initialized)
{
for(size_t i = 0; strings[i] != NULL; ++i)
myStringList[i] = hash(strings[i]);
hash_initialized = true;
}
if(hash_lookup(string))
{
...
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.