2011-09-30 113 views
8

我目前正在研究一个代码项目,要求我用这些字符串的散列替换某些字符串。由于这些字符串在运行时不会改变,因此让c预处理器对我声明在编译时被哈希的每个字符串运行我的哈希函数将是有利的,效率明智的。如何让C预处理器在编译期间执行代码?

有什么办法让编译时运行我的散列函数的预处理器?C

我知道这并不是我上面描述的方式,但只是想知道我要去哪里,这里有一些使用宏的伪代码。试想一下,而不是简单地扩大宏,预处理器运行散列函数,并将其扩展到该散列函数的返回值:

#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; 
    } 

再次,理想的cout << U64_HASH("thanks for helping me") << endl;将扩大到cout << 12223622566970860302 << endl;

我写的一个头文件生成器,并且这个项目工作正常。

最终解决

我已经决定使用John Purdy's perl script这个项目,因为它只是真棒,并让我给我希望直接输出喂到我的编译器。非常感谢,约翰。

+0

并非没有疯魔。 –

+0

C++ 11具有用户定义的文字和constexpr。这些可能会有所帮助。 – Pubby

+1

你总是可以将这些字符串定义为哈希值? AFAIK C预处理器没有任何运行代码的能力。 – Serdalis

回答

6

一种方法是把所有的字符串放到一个头文件,并将它们命名为:

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

然后就可以使用这些字符串:

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

然后你就可以运行程序在您的StringHeader.h上散列每个字符串,并生成替换头文件:

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

起初,这看起来非常手动和乏味,但有办法使它自动化。

例如,你可以写一些东西来解析你的源代码,寻找“引用字符串”。然后它可以命名每个字符串,将其写入一个StringHeader.h,并用新的命名字符串常量替换内联带引号的字符串。作为创建文件的附加步骤,您可以对每个字符串进行散列 - 或者在创建文件后,您可以一次性将文件散列。这可以让你创建一个哈希和非哈希版本的文件(这可以很好地创建一个非哈希的Debug版本,以及散列版本)。

如果你这样做,你的初始解析器查找字符串将不得不处理边缘情况(注释,#包括行,重复的字符串等)。

0

如果你不能让预处理器为你做这件事,你可以编写你自己的预处理器来先做这一步。

+1

是的,我正在考虑这一点,如果有必要的话会这样做,但如果可以的话,我真的很想使用标准预处理器。 –

0

有没有办法强制它,但如果你的编译器足够好,它可以做到这一点。玩它的优化选项,并研究调试器中的代码反汇编,看看它们中的任何一个是否可以让你实现你想要的。要做到这一点

+3

你可以命名一个编译器来执行你正在谈论的内容吗? –

+1

所有你必须做的事情是在宏本身中写入完整的散列 - 然后编译器应该将它看作一个常量表达式并替换该值(假设优化设置允许)。 Easy!*(* hard) – geofftnz

+0

@David:我认为DMD编译器可以通过CTFE做到这一点:)虽然我也很好奇它是否可以在C++中使用。从未听说过 –

6

如果编译器曾经支持这一点,C++ 11 user defined literals

constexpr unsigned long long operator "" U64_HASH_(
    const char *literal_string) { ... } 

#define U64_HASH(inputString) inputString U64_HASH_ 

constexpr

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

这是否保证返回字符串文字的哈希值? –

相关问题