我想使用gcc预处理器编写几乎相同的代码声明500次。让我们说出于演示目的,我想使用宏FOR_MACRO
:
#define FOR_MACRO(x) \
#for i in {1 ... x}: \
const int arr_len_##x[i] = {i};
并且调用FOR_MACRO(100)
将转换为:
const int arr_len_1[1] = {1};
const int arr_len_2[2] = {2};
...
const int arr_len_100[100] = {100};
答案 0 :(得分:10)
这不是一个好主意:
虽然原则上可行,但使用预处理器意味着您必须至少手动展开循环一次,最终会在循环深度上产生一些任意实现定义的限制,并且所有语句都将在一行中生成。
更好地使用您选择的脚本语言来生成代码(可能在单独的可包含文件中)并将其与您的构建过程集成。
答案 1 :(得分:3)
如果您迫切需要,可以使用Order-PP。
它是预处理器中实现的脚本语言。这意味着它在概念上类似于使用脚本语言生成C代码(事实上,相同),除了没有外部工具,并且脚本与C编译器同时运行:一切都是用C宏完成的。尽管是在预处理器上构建的,但循环迭代,递归深度或类似的东西没有真正的限制(限制在数十亿的某个地方,你不必担心它)。
要发出问题示例中请求的代码,您可以写:
#include <order/interpreter.h>
ORDER_PP( // runs Order code
8for_each_in_range(8fn(8I,
8print( 8cat(8(const int arr_len_), 8I)
([) 8I (] = {) 8I (};) )),
1, 101)
)
我无法理解为什么要这样做,而不是简单地将像Python这样的外部语言集成到您的构建过程中(订单可能是使用宏实现,但它仍然是一个单独的语言来理解),但选项就在那里。
据我所知,订单仅适用于海湾合作委员会;其他预处理器过快地耗尽堆栈(甚至是Clang),或者不完全符合标准。
答案 2 :(得分:1)
您确定不能以更好的方式处理问题,而不是为您提供完全解决问题的解决方案吗?
也许
会更好.bss
段而不是.data
,并且二进制文件中可能需要更少的空间。答案 3 :(得分:1)
您可以使用例如P99来执行此类预处理器代码展开。但由于预处理器的容量有限,因此有限制,并且该限制通常低于500
。