如何让C预处理器在编译过程中执行代码
How to have the C preprocessor execute code during compilation?
我目前正在进行一个代码项目,该项目要求我用这些字符串的哈希值替换某些字符串。由于这些字符串在运行时不会改变,因此在效率方面,让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的perl脚本,因为它非常棒,并且允许我直接向编译器提供我想要的输出。非常感谢,John。
实现此目的的一种方法是将所有字符串放入头文件中,并将其命名为:
// 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
,并用新的命名字符串常量替换内联引号字符串。作为创建文件时的附加步骤,您可以对每个字符串进行散列处理—或者您可以在创建文件后一次性处理该文件。这可以让您创建文件的散列和非散列版本(创建非散列调试版本和散列发布版本可能会很好)。
如果您尝试这样做,您的初始解析器查找字符串将不得不处理边缘情况(注释,#include行,重复字符串等)。
如果编译器支持这个,c++ 11有用户定义的字量:
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) { ... }
如果你不能让预处理器为你做这些,你可以先写你自己的预处理器来做这一步。
没有办法强制这样做,但如果编译器足够好,它可以这样做。使用它的优化选项,并在调试器中研究代码的反汇编,看看其中是否有任何一个选项可以让您实现想要的目标。
- clang 插件:在编译过程中修改 AST
- C++ 在编译过程中 strtok 函数 Eclipse 说没有在范围内声明?
- 运行程序时找不到共享对象库,但在编译过程中链接了它
- 为什么在编译过程中尽管有 -I(破折号大写 i)标志,但仍会出现未定义的引用错误?
- 如何在编译过程中输出C 类型信息
- 如何指示emscripten在编译过程中应在哪里找到源文件
- 编译过程中有许多错误opencv_contrib
- 在编译过程中组成一系列字符串
- 在编译过程中,琐碎的(没有效果的)代码什么时候会被删除
- C++ 'stod()'不起作用,'strtod()'编译过程中抛出错误
- C++;编译过程中的警告"enabled by default"是什么意思?
- 如何在编译过程中实现功能单元测试
- 在c++编译过程中,私有访问和公共访问是如何工作的
- 如何确保在C++编译过程中,参数将被视为常量
- 如何使用"python setup.py build"解决C++/C编译过程中的"conflicting types"错误?
- 如何在编译过程中编辑可执行文件,而不更改其源代码
- 编译过程中关于 boost 静态库的链接错误"undefined reference"
- Visual Studio 在编译过程中找不到头文件,尽管已指定包含目录
- 编译过程中出错
- 编译过程中无法从加速框架中链接BLAS -OS Yosemite 10.0.5