是否可以通过输入奇怪的源代码将GCC置于无限循环中?如果是,怎么样?也许人们可以用模板元程序设计做点什么?
答案 0 :(得分:11)
是
几乎每个计算机程序都有循环终止问题。我认为GCC会在无限循环变得明显之前耗尽RAM。其设计中没有很多“免费”操作。
解析器&预处理器不会产生问题。我愿意打赌你可以针对优化器,这可能会有更多的实现错误。它可能不是关于语言,更多的是利用您可以从源代码中发现的漏洞。即漏洞利用是不明显的。
<强>更新强>
在this particular case中,我的理论似乎是正确的。编译器不断分配RAM,优化器确实容易受到攻击。答案是肯定的。是的,你可以。
答案 1 :(得分:7)
错误特别短暂,例如@ Pestilence的答案在GCC 4.4.0中找到并在4.4.1中修复。有关将GCC置于无限循环的当前方法的列表,请检查their Bugzilla。
编辑:我刚刚发现了一种新的方式,也崩溃了Comeau。现在,这是一个更令人满意的答案。当然,它是should also be fixed soon。
template< int n >
struct a {
a< n+1 > operator->() { return a< n+1 >(); }
};
int main() {
a<0>()->x;
}
答案 2 :(得分:4)
由于C ++模板元编程实际上是图灵完成,你可以进行永无止境的编译。
例如:
template<typename T>
struct Loop {
typedef typename Loop<Loop<T> >::Temp Temp;
};
int main(int, char**) {
Loop<int> n;
return 0;
}
然而,就像我面前的答案一样。 gcc有一个标志来阻止它无休止地继续(就像无限递归中的堆栈溢出一样)。
答案 3 :(得分:1)
有可能。但是大多数编译器(以及大多数标准化语言)对模板或包含文件中的递归深度等内容都有限制,此时编译器应该使用诊断进行挽救。不这样做的编译器通常不会受到用户欢迎。
答案 4 :(得分:0)
我认为你可以用#include
只需#include“file1.c”进入file2.c并将#include“file2.c”放入file1
建议导致编译器循环很多然后失败,而不是无限循环
答案 5 :(得分:0)
不知道gcc,但旧的pcc曾经进入无限循环编译某些无限循环(编译为_x:jmp _x的那些循环)。
答案 6 :(得分:0)
Bentley在他的书“Programming Pearls”中写道,以下代码在优化编译期间导致无限循环:
void traverse(node* p) {
traverse(p->left);
traverse(p->right);
}
他说“优化器试图将尾递归转换为循环,并在找到终止循环的测试时死掉。” (第139页)他没有报告发生的确切编译器版本。我假设较新的编译器会检测到这种情况。