为了纪念Stack Overflow的公开发布,导致堆栈溢出的最短代码是什么?任何语言欢迎.
ETA:只是要明确这个问题,因为我偶尔会看到一个Scheme用户:尾调用"递归"实际上是迭代,任何可以通过合适的编译器相对简单地转换为迭代解决方案的解决方案都不会算一算 :-P
ETA2:我现在选择了"最佳答案"; 看这篇文章的理由.感谢所有贡献的人!:-)
阅读这一行,并做两次说.
所有这些答案都没有Befunge?我打赌相当多,这是他们所有人的最短解决方案:
1
不开玩笑.亲自尝试:http://www.quirkster.com/iano/js/befunge.html
编辑:我想我需要解释一下.1操作数将1推入Befunge的内部堆栈,缺少任何其他内容将其置于语言规则下的循环中.
使用提供的解释,你会最终-我的意思是最终 --hit一个地步Javascript数组,表示Befunge堆栈变得过大的浏览器重新分配.如果你有一个简单的Befunge解释器,它有一个较小的有限堆栈 - 就像下面大多数语言一样 - 这个程序会更快地引起更明显的溢出.
你也可以在C#.net中试试这个
throw new StackOverflowException();
Nemerle:
这会使编译器崩溃并发生StackOverflow异常:
def o(){[o()]}
我目前最好的(在x86组装中)是:
push eax jmp short $-1
这导致3个字节的目标代码(50 EB FD
).对于16位代码,这也是可能的:
call $
这也导致3个字节(E8 FD FF
).
TK给出的PIC18答案产生以下指令(二进制):
overflow PUSH 0000 0000 0000 0101 CALL overflow 1110 1100 0000 0000 0000 0000 0000 0000
但是,仅CALL将执行堆栈溢出:
CALL $ 1110 1100 0000 0000 0000 0000 0000 0000
但RCALL(相对调用)仍然较小(不是全局内存,所以不需要额外的2个字节):
RCALL $ 1101 1000 0000 0000
因此PIC18上最小的是单指令,16位(两个字节).这将在每个循环中花费2个指令周期.每个指令周期4个时钟周期,您有8个时钟周期.PIC18具有31级堆栈,因此在第32次循环之后,它将在256个时钟周期内溢出堆栈.在64MHz时,您将以4微秒和2个字节溢出堆栈.
但是,PIC16F5x系列使用12位指令:
CALL $ 1001 0000 0000
同样,每个循环两个指令周期,每个指令4个时钟,每个循环8个时钟周期.
但是,PIC16F5x具有两级堆栈,因此在第三个循环中它会溢出,在24条指令中.在20MHz时,它会在1.2微秒和1.5个字节内溢出.
在英特尔4004有一个8位CALL指令:
CALL $ 0101 0000
对于与ascii'P'相对应的好奇心.使用3级堆栈,需要24个时钟周期,总共32.4微秒和一个字节.(除非你超频你的4004 - 来吧,你知道你想要.)
这与befunge答案一样小,但比当前解释器中运行的befunge代码要快得多.
C#:
public int Foo { get { return Foo; } }
Hoot溢出!
// v___v let rec f o = f(o);(o) // ['---'] // -"---"-
每项任务都需要合适的工具.符合SO溢出语言,经过优化可产生堆栈溢出:
so
TeX的:
\def~{~.}~
结果是:
! TeX capacity exceeded, sorry [input stack size=5000]. ~->~ . ~->~ . ~->~ . ~->~ . ~->~ . ~->~ . ... <*> \def~{~.}~
胶乳:
\end\end
结果是:
! TeX capacity exceeded, sorry [input stack size=5000]. \end #1->\csname end#1 \endcsname \@checkend {#1}\expandafter \endgroup \if@e... <*> \end\end
Z-80汇编程序 - 在内存位置0x0000:
rst 00
一个字节 - 0xC7 - 将当前PC推送到堆栈并跳转到地址0x0000的无限循环.
用英语讲:
recursion = n. See recursion.
另一个PHP示例:
require(__FILE__);
BASIC中的以下内容如何:
10 GOSUB 10
(我没有BASIC翻译,我担心这是猜测).
我喜欢Cody的答案堆,所以这是我在C++中的类似贡献:
templateclass Overflow { typedef typename Overflow::type type; }; typedef Overflow<0>::type Kaboom;
无论如何都不是代码高尔夫球场,但是,元堆栈的任何东西都会溢出!:-P
这是我的C贡献,重量为18个字符:
void o(){o();o();}
这是一个很多难以尾调用优化!:-P
使用名为"s.bat"的Window批处理文件:
call s
使用Javascript
为了削减更多的角色,并让自己从更多的软件商店中被踢出来,让我们一起来:
eval(i='eval(i)');
Groovy的:
main()
$ groovy stack.groovy:
Caught: java.lang.StackOverflowError at stack.main(stack.groovy) at stack.run(stack.groovy:1) ...
请告诉我" GNU " 的缩写.
Person JeffAtwood; Person JoelSpolsky; JeffAtwood.TalkTo(JoelSpolsky);
这里希望没有尾递归!
C - 它不是最短的,但它是无递归的.它也不可移植:它在Solaris上崩溃,但是一些alloca()实现可能在这里返回错误(或调用malloc()).对printf()的调用是必要的.
#include#include #include int main(int argc, char *argv[]) { struct rlimit rl = {0}; getrlimit(RLIMIT_STACK, &rl); (void) alloca(rl.rlim_cur); printf("Goodbye, world\n"); return 0; }
Python:
so=lambda:so();so()
或者:
def so():so() so()
如果Python优化尾调用...:
o=lambda:map(o,o());o()
perl in 12 chars:
$_=sub{&$_};&$_
bash in 10 chars(函数中的空格很重要):
i(){ i;};i
尝试在一个汉堡上放4个以上的肉饼.堆栈溢出.
我在这篇文章后选择了"最佳答案".但首先,我要感谢一些非常原始的贡献:
aku的.每一个都探索了一种导致堆栈溢出的新的原始方法.做f(x)⇒f(f(x))的想法是我将在下一个条目中探讨的.:-)
Cody是给Nemerle 编译器堆栈溢出的一个.
而且(有点勉强),GateKiller是一个关于抛出堆栈溢出异常的人.:-P
就像我喜欢上述情况一样,挑战在于打高尔夫球,对于受访者来说,我必须对最短的代码(Befunge入门)给予"最佳答案"; 我不相信任何人都能击败它(虽然康拉德当然已经尝试过),所以恭喜帕特里克!
看到大量的堆栈溢出递归解决方案,我很惊讶没有人(截至当前的写作)提出Y组合器(参见Dick Gabriel的文章,为什么Y,作为入门).我有一个使用Y组合器的递归解决方案,以及aku的f(f(x))方法.:-)
((Y (lambda (f) (lambda (x) (f (f x))))) #f)
这是Scheme中另一个有趣的:
((lambda (x) (x x)) (lambda (x) (x x)))
Java的
Java解决方案的版本略微缩短.
class X{public static void main(String[]a){main(a);}}
xor esp, esp ret
3个字节:
label:
pusha
jmp label
label: call label