How to make C preprocessor execute code at compile time?

I am currently working on a code project that requires me to replace some strings with hashes of those strings. Since these lines will not change at runtime, it would be useful, in terms of efficiency, for the c preprocessor to execute my hash function for every line that I declare hashed at compile time.

Is there a way to get the C preprocessor to run my hash function at compile time?

I know that this does not work as I described above, but just to understand where I am going, here is some kind of pseudo code that uses a macro. Imagine that instead of simply expanding the macro, the preprocessor ran the hash function and expanded it to the return value of this hash function:

#include <iostream> #include <string> #define U64_HASH(inputString) getU64HashCode(inputString) //my hash function unsigned long long getU64HashCode (string inputString) { /*code*/ } int main() { cout << U64_HASH("thanks for helping me") << endl; return 0; } 

Again, ideally cout << U64_HASH("thanks for helping me") << endl; will expand to cout << 12223622566970860302 << endl;

I wrote a header file generator and it works great for this project.

Final decision

I decided to use the John Purdy perl script for this project, since it is just awesome and allows me to feed the output I want directly to my compiler. Thanks a lot, John.

+8
c ++ c-preprocessor
source share
4 answers

One way to achieve this is to put all your lines in a header file and name them:

 // StringHeader.h #define helloWorld "Hello World" #define error_invalid_input "Error: Invalid Input" #define this_could_get_tedious "this could get tedious" 

Then you can use these lines:

 #include "StringHeader.h" std::cout << this_could_get_tedious << std::endl; 

Then you can run the program on StringHeader.h to hash each line and generate a replacement header file:

 // Generated StringHeader.h #define helloWorld 097148937421 #define error_invalid_input 014782672317 #define this_could_get_tedious 894792738384 

It looks very tame and tedious, but there are ways to automate it.

For example, you can write something to parse the source code by looking for "quoted strings." He can then name each line, write it to one StringHeader.h and replace the line of the line specified in the line with a new named string constant. As an additional step when creating a file, you can hash each line - or you can have the file at a time after creating it. This may allow you to create a hashed and non-hashed version of the file (which would be nice to create a non-hashed version of Debug and a hashed version of Release).

If you try to do this, your initial line parser will have to handle boundary cases (comments, #include lines, duplicate lines, etc.).

+6
source share

If the compiler ever supports this, in C ++ 11 user literals :

 constexpr unsigned long long operator "" U64_HASH_( const char *literal_string) { ... } #define U64_HASH(inputString) inputString U64_HASH_ 

or with constexpr :

 constexpr unsigned long long operator "" U64_HASH( const char *literal_string) { ... } 
+6
source share

If you cannot get the preprocessor to do this for you, you can write your own preprocessor to take this step first.

0
source share

There is no way to force it, but if your compiler is good enough, it can do it. Play with the optimization options and examine the code debugging in the debugger to see if any of them allow you to achieve what you want.

0
source share

All Articles