检测 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%?)
我正在寻找一种方法来检测或缓解 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%?)