如何让C预处理器在编译期间执行代码?

Mic*_*fen 8 c++ c-preprocessor

我目前正在开发一个代码项目,要求我用这些字符串的哈希值替换某些字符串.看到这些字符串在运行时不会改变,因此让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;
    }
Run Code Online (Sandbox Code Playgroud)

再次,理想情况下,cout << U64_HASH("thanks for helping me") << endl;将扩展到cout << 12223622566970860302 << endl;

我写了一个头文件生成器,这对这个项目很好.

最终解决方案

我决定在这个项目中使用John Purdy的perl脚本,因为它非常棒,并且允许我将我想要的输出直接提供给我的编译器.非常感谢,约翰.

Tim*_*Tim 6

实现此目的的一种方法是将所有字符串放入头文件中,并将其命名为:

// StringHeader.h
#define   helloWorld              "Hello World"
#define   error_invalid_input     "Error: Invalid Input"
#define   this_could_get_tedious  "this could get tedious"
Run Code Online (Sandbox Code Playgroud)

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

#include "StringHeader.h"
std::cout << this_could_get_tedious << std::endl;
Run Code Online (Sandbox Code Playgroud)

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

// Generated StringHeader.h
#define   helloWorld              097148937421
#define   error_invalid_input     014782672317
#define   this_could_get_tedious  894792738384
Run Code Online (Sandbox Code Playgroud)

起初看起来非常手动和繁琐,但有办法让它自动化.

例如,您可以编写一些内容来解析源代码,查找"引用字符串".然后它可以命名每个字符串,将其写入单个字符串,StringHeader.h并用新命名的字符串常量替换内联引用的字符串.作为创建文件的另一个步骤,您可以对每个字符串进行哈希处理 - 或者您可以在创建文件后一次性使用该文件.这可以让你创建一个散列和非散列版本的文件(这可能很好地创建一个非散列的调试版本和散列的发行版本).

如果您尝试这样做,那么查找字符串的初始解析器将必须处理边缘情况(注释,#include行,重复字符串等).


MSN*_*MSN 6

如果编译器支持这一点,C++ 11具有用户定义的文字:

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

#define U64_HASH(inputString) inputString U64_HASH_
Run Code Online (Sandbox Code Playgroud)

或者constexpr:

constexpr unsigned long long operator "" U64_HASH(
    const char *literal_string) { ... }
Run Code Online (Sandbox Code Playgroud)