Any way to generate hash from string at compile time?

Humus

Crazy coder
Veteran
I'd like to be able to have a static string converted to a hash value at compile time rather than generating code to evaluate it.

Like this:
Code:
const int hash = GetHash("MyFancyString");

But have the compiler generate this code for instance:
Code:
const int hash = 0x28AC8B1F;

If the GetHash() function is sufficiently simple and the string is sufficiently short MSVC will do this for me, but if the string is longer than 10 chars it will generate a function call instead. Is there any way to force the compiler evaluate more than 10 chars? Or any magic construct that will force the compiler evaluate it completely?

From what I gather there's a solution in C++0x with variadic templates and user-defined literals, but while waiting for compilers to implement this I was hoping for a standard c++ way of doing things. Any suggestions?
 
I'm not sure you can use a macro to do this. What I might try is using a pre-build step to generate a header file with preprocessor definitions for your string keys, i.e.

Code:
// strings.h
#define MY_FANCY_STRING 0x28AC8B1F

The header is generated at compile time and you just include it where you need to reference your string keys.

This is at least how I've seen more than one localization system implemented, and it works quite well -- much more performant than runtime hashing or string-by-string lookups. The only drawback is that you have to recompile if you want to change your strings. You could use Excel for the string storage and a macro to generate the headers.
 
I don't know of a way inside the c-preprocessor, but, personally, I'd use *nix/Gnu make to first compile & run a trivial program that simply includes your strings .h file and spits the hashes out into another ".h"

Simon
 
Make's unneccessary. Just create a pre-build step in Visual Studio. You could also create a project for it and specify it as a dependency in the solution.
 
I've seen it done two ways withTemplates, but nothing like as tidilly as the original code you posted.
I've seen both ways fail to generate the constant you would expect under edge cases.
We used to resort to a macro that would take the string and convert it to
0x28AC8B1f /* My Fancy String */

Rob
 
I was emailed a solution:
http://www.gamedev.net/community/forums/topic.asp?topic_id=550505&whichpage=1&#3545090

I have verified that this does indeed work on MSVC 2008 at least, but supposedly works fine on other compilers as well. Only thing is you have to implement the template for all string lengths you wish to support and each implementation must be manually unrolled. Pushing all that dirty stuff away into a header file though and it should work nicely.
 
That's one of the variations I've seen, it doesn't work in case statements for the obvious reason and we saw the compiler occasionally not do the constant folding, so it ended up deprecated in our codebase.
 
Back
Top