对于在预处理器阶段展开的循环宏?

我想使用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}; 

这不是一个好主意:

尽管原则上可行,但使用预处理器意味着您必须至少手动展开循环一次,最终会在循环深度上产生一些任意实现定义的限制,并且所有语句都将在一行中生成。

更好地使用您选择的脚本语言来生成代码(可能在单独的可包含文件中)并将其与您的构建过程集成。

如果您迫切需要,可以使用Order-PP 。

它是预处理器中实现的脚本语言。 这意味着它在概念上类似于使用脚本语言生成C代码(事实上,相同),除了没有外部工具,并且脚本与C编译器同时运行:一切都是用C宏完成的。 尽管是在预处理器上构建的,但循环迭代,递归深度或类似的东西没有真正的限制(限制在数十亿的某个地方,你不必担心它)。

要发出问题示例中请求的代码,您可以编写:

 #include  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),或者不完全符合标准。

而不是为您提供完全解决问题的解决方案,您确定无法以更好的方式处理它吗?

也许它会更好

  • 使用一个具有一个维度的数组
  • 在运行时使用数组填充数据,因为您显然希望填写每个数组的第一个条目。 如果你保持数组未初始化,它将(假设它在模块级别定义)被放入.bss段而不是.data并且可能在二进制文件中需要更少的空间。

您可以使用例如P99来执行此类预处理器代码展开。 但由于预处理器的容量有限,因此有一个限制,并且该限制通常低于500