检测 C/C++ 预处理器滥用导致巨大的扩展代码大小

Detect C/C++ preprocessor abuse that leads to huge expanded code sizes

我正在寻找一种方法来检测或缓解 C++ 源代码,这些源代码在预处理时会扩展到巨大的大小,从而导致 GCC 耗尽内存。

示例代码:

#include <iostream>
using namespace std;
int main() {
    #define A30 cout << "hello world";
    #define A29 if (1) { A30 } else { A30 }
    #define A28 if (0) { A29 } else { A29 }
    // ... you get the idea ... 
    #define A1 if (1) { A2 } else { A2 }
    #define A0 if (0) { A1 } else { A1 }
    A0
    return 0;
}

编译这个程序应该会生成一个巨大的、语法正确的 if-else 树(适用于较小的版本;比如说,最高 A10);如果执行,它会简单地打印该树中的 2^30 "hello world" 个字符串之一。但是,尝试在 8GB 机器上编译会导致无响应行为,并且(一段时间后)显示以下错误:

internal compiler error: Segmentation fault
A0
^

是否可以使用 GCC 4.9.x 限制上述情况下的预处理器扩展,或者避免此类程序崩溃?

据我所知,没有办法通过简单的 gcc 命令实现您想要实现的目标。 解决它的方法可能是在您的构建系统中添加一些额外的步骤,以查看提交是否将代码库增加了一定百分比。

您在 gcc 中有一个选项 (-E) 可以在预处理器步骤后输出代码。

如果您在提交 1 时进行构建,则可以保存该提交时的行数,运行 gcc with -E,并在其输出上执行 "wc -l"。

在提交 2 时,在构建之前,您执行相同的操作,并检查行数是否没有增加您定义的阈值(10%、20%?)