什么是导致堆栈溢出的最短代码?

为了纪念Stack Overflow的公开发行,导致堆栈溢出的最短代码是什么? 欢迎任何语言。

ETA:为了清楚这个问题,看看我是一个偶然的Scheme用户:tail-call“recursion”是真正的迭代,任何可以通过体面的编译器相对简单地转换成迭代解决scheme的解决scheme将不会被算。 😛

ETA2:我现在select了一个“最佳答案”。 看到这个职位的理由。 感谢大家的贡献! 🙂

所有这些答案,没有Befunge? 我敢打赌,这是他们最短的解决scheme:

1 

不开玩笑。 尝试一下: http : //www.quirkster.com/iano/js/befunge.html

编辑:我想我需要解释这一个。 1操作数将1推到Befunge的内部堆栈上,而其他任何东西都不会在语言规则下进行循环。

使用所提供的解释器,您最终将会 – 也就是说最终 – 代表Befunge堆栈的JavaScript数组变得太大而无法重新分配浏览器。 如果你有一个简单的Befunge解释器,它有一个更小的和有界的堆栈 – 就像大多数下面的语言一样 – 这个程序会更快地引起更明显的溢出。

阅读这条线,做两次

你也可以在C#.net中试试这个

 throw new StackOverflowException(); 

Nemerle

这使用StackOverflowException 导致编译器崩溃

 def o(){[o()]} 

我目前最好的(在x86程序集)是:

 push eax jmp short $-1 

这导致了3个字节的目标代码( 50 EB FD )。 对于16位代码,这也是可能的:

 call $ 

这也导致3个字节( E8 FD FF )。

PIC18

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 

更小,更快的PIC18

但RCALL(相对调用)仍然较小(不是全局内存,所以不需要额外的2个字节):

 RCALL $ 1101 1000 0000 0000 

所以在PIC18上最小的是一个指令,16位(两个字节)。 这将需要每个循环2个指令周期。 在每个指令周期4个时钟周期,你有8个时钟周期。 PIC18具有31级堆栈,因此在第32个循环之后,将以256个时钟周期溢出堆栈。 在64MHz时,你会在4微秒和2字节溢出堆栈

PIC16F5x(甚至更小,更快)

但是,PIC16F5x系列使用12位指令:

 CALL $ 1001 0000 0000 

再次,每个循环两个指令周期,每个指令4个时钟,因此每个循环8个时钟周期。

但是,PIC16F5x具有两级堆栈,所以在第三级循环中,会有24条指令溢出。 在20MHz时,会在1.2微秒和1.5字节溢出

英特尔4004

英特尔4004有一个8位调用子程序指令:

 CALL $ 0101 0000 

对于对应于ascii“P”的好奇。 使用3级堆栈需要24个时钟周期,总共32.4微秒和一个字节 。 (除非你超频你的4004 – 来吧,你知道你想要。)

这与befunge的答案一样小,但比当前解释器中运行的befunge代码要快得多。

C#:

 public int Foo { get { return Foo; } } 

Hoot溢出!

 // v___v let rec fo = f(o);(o) // ['---'] // -"---"- 

每个任务都需要正确的工具。 符合SO溢出语言,优化产生堆栈溢出:

 so 

TeX的:

 \def~{~.}~ 

结果是:

  ! 超过TeX容量,抱歉[input堆栈大小= 5000]。
 〜 - >〜
     。
 〜 - >〜
     。
 〜 - >〜
     。
 〜 - >〜
     。
 〜 - >〜
     。
 〜 - >〜
     。
 ...
 <*> \ def〜{〜。}〜 

胶乳:

 \end\end 

结果是:

  ! 超过TeX容量,抱歉[input堆栈大小= 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 ++中的类似贡献:

 template <int i> class Overflow { typedef typename Overflow<i + 1>::type type; }; typedef Overflow<0>::type Kaboom; 

不是以任何方式代码高尔夫项目,但仍然是任何元堆栈溢出! 😛

这是我的C贡献,重达18个字符:

 void o(){o();o();} 

这是一个很难的尾调优化! 😛

使用名为“s.bat”的窗口batch file:

 call s 

使用Javascript

为了修剪更多的angular色,并让自己从更多的软件商店中走出来,让我们继续:

 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); 

这里希望没有尾recursion!

C – 这不是最短的,而是无recursion的。 它也不是可移植的:它在Solaris上崩溃,但是一些alloca()实现可能在这里返回错误(或者调用malloc())。 调用printf()是必要的。

 #include <stdio.h> #include <alloca.h> #include <sys/resource.h> 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; } 

perl 12个字符:

 $_=sub{&$_};&$_ 

bash在10个字符(function中的空间是重要的):

 i(){ i;};i 

尝试在一个汉堡上放4个以上的馅饼。 堆栈溢出。

Python

 so=lambda:so();so() 

或者:

 def so():so() so() 

如果Python优化了尾部调用…:

 o=lambda:map(o,o());o() 

我在这篇文章之后select了“最佳答案”。 但首先,我要感谢一些非常独创的贡献:

  1. aku的。 每一个探索导致堆栈溢出一个新的和原始的方式。 做f(x)⇒f(f(x))的想法是我将在下面的下一个条目中探讨的。 🙂
  2. 科迪的一个给了Nemerle 编译器一个堆栈溢出。
  3. 和(有点勉强),GateKiller的一个关于抛出堆栈溢出exception。 😛

就像我喜欢上面的那样,挑战是做代码高尔夫球,为了公平地回答问题,我必须给最短的代码“Befunge”条目授予“最佳答案”。 我不相信有人能够打败他(虽然康拉德当然试过了),所以恭喜帕特里克!

看到大量的堆栈溢出解决scheme,我很惊讶没有人(如目前的写作)提出了Y组合(见迪克·加布里埃尔的文章, 为什么Y ,作为一个引子)。 我有一个使用Y组合器的recursion解决scheme,以及aku的f(f(x))方法。 🙂

 ((Y (lambda (f) (lambda (x) (f (fx))))) #f) 

这是另一个有趣的计划:

  ((lambda(x)(xx))(lambda(x)(xx))) 

Java的

Java解决scheme的稍微缩短版本。

 class X{public static void main(String[]a){main(a);}} 
 xor esp, esp ret 

3个字节:

标签:
   PUSHA
   jmp标签

更新

根据(旧?)Intel(?)文档 ,这也是3个字节:

标签:
  呼叫标签