【问题标题】:Code-Golf: What is the shortest program that compiles and crashes?Code-Golf:编译和崩溃的最短程序是什么?
【发布时间】:2010-12-18 17:33:06
【问题描述】:

这有点有趣。你能设计出最短的程序,它可以编译,但在执行时会立即崩溃?因此,“崩溃”是指程序因错误情况而停止(例如核心转储)。

使用 gcc 编译器,有没有一种语言比 C 崩溃得更快(7 个字符)? [我把这个答案留给别人找。]

(应该允许使用编译器标志。否则现在 7 将无法工作,编译器检查变得更好。)

[结果评估] 我无法标记一个答案,因为多种语言有多个正确答案。取消一个答案的资格是不公平的。请使用投票来选择最佳答案。

【问题讨论】:

  • “崩溃”是什么意思?它是否必须导致错误,它会陷入无限循环吗?还是必须把整台机器都拆下来?
  • 你不能用 7 个字符编写一个有效的 C 程序根本
  • 这是一个真正的问题 - 这是一个代码高尔夫
  • 不遵守 Code-Golf 规则...
  • 关闭整个网络的奖励积分。

标签: programming-languages code-golf


【解决方案1】:

呸——我可以在 5 个字符内使 C 崩溃:

main;

这声明了一个名为“main”的隐式int 变量。 它是全局变量,因此变量的初始值为0。 它是 C 名称没有修饰 - 所以链接器没有意识到它是一个 var 而不是一个函数。

GCC 给了我一个警告 - 仅此而已。

$ gcc crash.c 
crash.c:1: warning: data definition has no type or storage class
$ ./a.exe
Segmentation fault (core dumped)
$

【讨论】:

  • 谢谢,这至少比我在问题中提到的答案短(在适当的情况下应用“=0”)。解释涵盖了它。
  • 如果你在 valgrind 下运行它会更有趣:valgrind: the 'impossible' happened: ...
  • 未定义行为 :)
【解决方案2】:

0 字符崩溃:

$ > golf.c
$ gcc -Wl,--defsym=main=0 golf.c
$ ./a.out
Segmentation fault

【讨论】:

  • 和我(暂时)没有投票权
  • Pssh,使用特殊的编译器标志应该包含在字符数中。 =]
  • 遗憾的是,您仍然没有:命令行开关会影响您的笔划。 :)
  • 我把这篇文章作为一个例子,命令行可以做任何事情(包括创建一个将代码附加到一个空文件中的 shell 命令,并将该 shell 命令声明为编译器)。我认为这个问题应该有一个更精确的规则集。
  • @paxdiablo:我认为一个空程序作为某种语言中最短的自输出程序提交给了混淆 C 竞赛。欢闹接踵而至。但我可能会将不同的事件混为一谈。
【解决方案3】:

不知道这算不算……

a

这是在 JavaScript 中。这给出了“找不到对象”的 runtime 错误。由于 JavaScript 是一种动态语言,因此在语法上这实际上是正确的。仍然感觉像是在扭曲规则。 :P

【讨论】:

  • 这真的是一个有效的陈述吗?它至少不需要分号或其他东西吗?
  • @roe: IIRC,分号在 Javascript 中用作语句之间的分隔符,所以你不需要在最后一个语句之后。
  • 我应该区分编译器语言和脚本语言,但后来我们争论了什么是脚本语言。 (这也适用于 python。)
  • @roe 是的,这是一个有效的声明,因为 javascript 将执行分号插入。此外,就像 C 语言一样,javascript 中允许无意义的评估语句,someVar; 并没有真正做任何有用的事情,但变量被评估并且它是规范的一部分。
  • 实际上,分号在 JavaScript 中是完全可选的。自己试试吧!是的 - 我想这可能适用于各种动态脚本语言。我只是不熟悉其他任何人。
【解决方案4】:

使用python:

1/0

【讨论】:

  • 3 个字符,确实很短。
  • 我倾向于称其为赢家,尤其是因为这也适用于其他脚本语言(我尝试了 ruby​​ 和 perl,显然 matlab 等也应该工作。)
  • 阅读 Vilx 答案后,我想到了更好的方法:a 将因 NameError 而崩溃。
  • 为什么不只是x? NameError 只是一个例外,语法是有效的。
【解决方案5】:

X86机器码:1字节

在 windows 的 cmd 提示符下创建包含字节 F4、x86 停止指令的文件 a.com:

F:\>debug
-a 100
0BFD:0100 hlt
0BFD:0101
-r cx
CX 0000
:1
-n a.com
-w
Writing 00001 bytes
-q

F:\>a.com

NTVDM CPU 遇到非法指令

【讨论】:

  • DOS 的 "*.COM" 格式需要零开销,但 UNIX 通常使用 ELF 来执行可执行文件,这在概念上类似于 Windows 的 PE:标题和节,而且不可能低于 45 字节(@987654321 @)
【解决方案6】:
$ cat > crash.S
hlt
$ as -o crash.o crash.S
$ ld crash.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048054
$ ./a.out
Segmentation fault

【讨论】:

  • 迄今为止最短的汇编程序。
【解决方案7】:

Perl

die
死于测试线 1。

die

将 LIST 的值打印到 STDERR 并以 $ 的当前值退出! (错误号)。

【讨论】:

  • 这在技术上是崩溃吗?它正在按照你的要求做:-)
  • 所有程序崩溃时也是如此......这只是更简单一点。
  • 我想你可以用a()替换它
  • 这不仅会按要求崩溃,而且也是最易读的。
  • 我看到的第一个问题,Perl 在哪里有最易读的解决方案。
【解决方案8】:

Commodore 64 BASIC:

poke 2,2:sys2

或更短(使用 PETSCII 图形字符快捷方式):

pO2,2:sY2

(崩溃:MOS/CSG6510 上的 $02 操作码无效)。实际上它可以在 7 个字节(3 条指令)中完成:

lda #$02
sta $02
jmp $0002

【讨论】:

  • Commodore 64 基本版 +1。我会给你更多,可惜堆栈溢出不允许我。
  • @mlk:在那里,为你解决了这个问题
  • 建议改进:戳1,0(或pO1,0,5个字符)进行银行切换。现在 CPU 将从内存中运行随机垃圾而不是 BASIC 解释代码,从而导致冻结。
【解决方案9】:

如果您在有 TI-89 的计算机商店,您可以通过输入以下内容来崩溃:

Exec "00000000"

(那是 8 个零)

它将产生“非法指令”。按 2nd+Left+Right+ON 重置计算。

如果您想玩得更开心,请这样做:

Exec "4E4A4E750000"

这会启动隐藏的硬件测试菜单,包括内存测试、LCD 测试(绘制棋盘等)等等。不幸的是,状态栏被删除了,并且 calc 的操作系统中没有任何内容将其拉回,所以要自己清理,按照上面的说明重置,或者这样做:

Exec "307C56E670FF20C020C020C020C020C04E750000"

【讨论】:

  • 你可以通过Execing 几乎所有无效的东西来崩溃它。
【解决方案10】:

大脑f*ck

5 个字符

+[>+]

这需要一段时间,但最终程序会耗尽内存并不可避免地崩溃。

【讨论】:

  • 不适用于使用内存包装的编译器。
  • 那些不是图灵完备的。那里的乐趣在哪里?
【解决方案11】:

因子(或 Forth)

.

“数据栈下溢”

【讨论】:

    【解决方案12】:

    java Z 怎么样?如果不存在文件,它将“崩溃”并显示java.lang.NoClassDefFoundError。所以我的答案是零字母。如果那无效,那么...

    class T{}
    

    会“崩溃” $java T 线程“main”中的异常 java.lang.NoSuchMethodError: main

    如果你想要一些实际运行的东西,那么如果你愿意稍微滥用一些东西

    class T{static {int i =1/0;}}
    

    否则

    class T{public static void main(String[]a){main(a);}}
    

    【讨论】:

    • T 和 {} 之间的空格是做什么用的? :-)
    【解决方案13】:

    引用this answer:

    所有这些答案都没有 Befunge? ID 下注合理的金额,它是最短的 全部解决:

    1
    

    不开玩笑。自己试试: http://www.quirkster.com/js/befunge.html

    编辑:我想我需要解释一下 一。 1 操作数将 1 推到 Befunge的内部堆栈和缺乏 其他任何东西都会把它放在一个循环中 根据语言规则。

    使用提供的解释器,您 最终会——我的意思是 最终——达到一个点 表示 Javascript 数组 Befunge 堆栈变得太大 浏览器重新分配。如果你有 一个简单的 Befunge 解释器 更小和有界的堆栈——就像 大多数语言的案例 下面——这个程序会导致更多 明显溢出更快。

    【讨论】:

      【解决方案14】:

      在 C 中,20 个字符:

      void main(){main();}
      

      更新:由 roe 建议,15 个字符:

      main(){main();}
      

      注意:使用 VC++ 2008 测试。

      【讨论】:

      • 根据标准无效:-)
      • "main(){return main();}" 是。
      • 实际上它应该在经过大量递归后崩溃。因此根据问题“工作”。
      • @paxdiablo:没有“标准”,只有 C99 标准和 C89 标准(还有很多其他标准)。 x(){...} 在早期的 C 标准中对 int x(void) {...} 完全有效。所以在该标准下它是有效的 C。
      • 那么,即使按照标准无效,有什么问题呢?它编译崩溃
      【解决方案15】:

      晚了,但无论如何。 PHP,32 个字符。

      $r=function($z){$z($z);};$r($r);
      

      Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 261900 bytes) in ...

      从技术上讲,我也可以在 29 中使用

      $r=function($z){$z();};$r(0);
      

      但这没有无限递归那么有趣。那,我不认为“未定义的函数”错误应该算作脚本语言中的“编译”,否则:

      Z();
      

      将是最小的解决方案。

      另外,如果(作为脚本)超过最大执行时间,而不是崩溃呢? 8 个字符:

      for(;;);
      

      我最初的看法是,在 for 循环的第三个表达式中有一个 $i++,但是因为 PHP 将所有整数都视为有符号,而不是溢出,它只是变为负数。

      【讨论】:

      • 喜欢这个 PHP 崩溃分析的冗长
      【解决方案16】:

      在汇编中试试这个:

      push 0
      ret
      

      当然要添加所有其他垃圾以编译到应用程序中。

      【讨论】:

      • 因为您可能可以构建一个自动编译这些垃圾的汇编程序,这可能是有效的。但是我其实不知道有没有这样的汇编器。
      • a86 就是这样一个野兽 - 不需要那些困扰 masm 的 gumpff。
      【解决方案17】:

      在windows powershell中:

      throw
      

      【讨论】:

      • 1/0 技巧在 powershell 中也是如此。没有理由浪费两个无辜的角色;-)
      • :) (我只是想插入这个笑脸,但所以要求 cmets 至少有 15 个字符长,所以浪费了 158 个无辜的字符。对不起。)
      【解决方案18】:

      Perl 只有 2 个字符。

      &a
      
      未定义的子程序 &main::a 在 test.pl 第 1 行调用。

      【讨论】:

        【解决方案19】:

        方案:

        (1)
        

        填充文本以使其更长。

        【讨论】:

        • 我知道我来晚了,但这真的可以编译吗?
        • 回答:没有。 Racket and Chicken(至少)拒绝从该“程序”构建可执行文件。鸡说“语法错误:非法原子形式”。 Racket 说“#%app:缺少过程表达式;可能最初是 (),这是一个非法的空应用程序:(#%app)”。我想几乎任何其他编译器都会做类似的事情。
        • 您可以通过添加一个字符来解决此问题:(1) 可以正常编译但会立即崩溃。
        • @dfeuer:没错 :) IIRC,Chez 实际上允许这样做,但它不会崩溃。它将其解释为'()
        • () 解释为'() 在Scheme 中是奇怪的,虽然我相信它在LISP 中是传统的。
        【解决方案20】:

        在 QBasic 中:

        ? 1/0
        

        (至少我认为它仍然会编译,然后被零除而崩溃;已经有一段时间了......)

        【讨论】:

        • QBasic 不能编译,QuickBASIC 可以:)
        • 在 Q.*Basic 中完全是文盲,我确实认识到与其他脚本语言的联系。由于(完全没有必要,当然 g)问号和回答未定义答案的简单问题所需的空间,QBasic 在可崩溃性方面失去了分数。
        • 我不认为这个空间是必要的。
        【解决方案21】:

        在 C 中,33 个字符:

        int main(void){return*((int*)0);}
        

        【讨论】:

        • 你可以在函数声明中省略void...不是最好的但是。
        • 如果你想遵循标准,你不能。 'int main(int,char*[])' 和 'int main(void)' 是仅有的两种保证形式。
        • 返回一个取消引用的空指针,即使没有赋值,也可以解决问题。
        • @paxdiablo:根据什么标准?我很确定至少在 C89 中省略声明 int x(void) {...}x() {...} 是合法的,C++ 完全是另一回事。
        • 当前标准 C99 和 C1x 草案都声明这两种形式是唯一有保证的形式。
        【解决方案22】:

        Golfscript - 1 个字符

        很多运营商都可以做到,例如

        *
        
        (eval):1:in `initialize': nil:NilClass (NoMethodError) 的未定义方法 `class_id' 来自 ../golfscript.rb:285:in `call' 来自 ../golfscript.rb:285:in `go' 从(评估):1:在“初始化”中 来自 ../golfscript.rb:285:in `call' 来自 ../golfscript.rb:285:in `go' 来自../golfscript.rb:477

        【讨论】:

          【解决方案23】:
          main = undefined
          

          在 Haskell 中。

          【讨论】:

          • 短:main=main(至少使用 GHC 生成 <<loop>>
          • 中等大小但便于携带:main = error ""
          【解决方案24】:

          F# 3 个字符

          1/0

          会编译,但会发出警告。

          【讨论】:

          • 我们可以称之为几乎终极的脚本破坏者。 ;-)
          • 啊..是的,但在 Haskell 1/0 中计算为无穷大。滚开,你们这些糟糕的编剧!
          • @unknown(yahoo):Haskell 在数学上是错误的。 1/0 不是无穷大,它是未定义的 - 重新排列方程:无穷大 * 0 == 1?不太可能。我依稀记得在我的工程课程中,讲师构建了一个系统,其中除以零的结果有效。
          • 1/0 计算为Infinity,前提是它的类型正确。 FloatDouble 可以,而Integer 会抱怨(因为它不是Fractional 并且不支持/),Rational 也会抱怨(因为不允许零分母)。 FloatDouble 类型表现出 IEEE 定义的行为,将 NaNInfinity 作为可能的值,并且在数学上完全不正确,因为 100000000000000000000000000000000000000 + 1.0 == 100000000000000000000000000000000000000 的计算结果为 True。 :-)
          【解决方案25】:

          Lua,3 个字符

          除以零在 Lua 中不会导致问题,但这里的内容很短:

          a()
          

          给出:

          lua: isort.lua:1: 尝试调用全局 'a' (一个 nil 值) 堆栈回溯: a.lua:1: 在主块中 [C]: ?

          【讨论】:

          • Lua 可以被零除吗?愿意分享结果吗?
          • Lua 对数字使用双精度浮点值,因此在 Windows 上为 print(1/0) --> 1.#INF 在 Linux 上为 print(1/0) --> inf
          【解决方案26】:

          F#,11 个字符

          box 0 :?> unit
          

          编译时没有警告。崩溃: System.InvalidCastException:无法将“System.Int32”类型的对象转换为“Microsoft.FSharp.Core.Unit”类型。

          【讨论】:

            【解决方案27】:

            PostScript,1 个字符

            喜欢 GolfScript:

            *
            

            语法合法,但在运行时崩溃,因为未定义标记 *(与 GolfScript 崩溃的原因不同)。

            【讨论】:

              【解决方案28】:
              int main () { int n = 0; return 1 / n; }
              

              【讨论】:

              • 你不能把它缩短到 int n = 1/0; ?
              • 那不能像return 1/0一样短吗?
              • 这不是一个完整的程序 :-)
              • @Developer Art:您可能会通过不使用编译器检查来欺骗编译器。
              • 你可以试试return 1/(0,0); :)
              【解决方案29】:

              这取决于线程允许的最大堆栈大小。但是使用 VC9 编译时确实会崩溃:

              int main()
              {
                  int a[10000000];
                  return 0;
              };
              

              【讨论】:

              • 由于这种情况,它不能被接受为“通用”解决方案。但很简单。
              【解决方案30】:

              Perl

              3 个字符

              1/0
              

              生产:

              Illegal division by zero at crash.pl line 1.
              

              (仍在寻找可以一分为二的东西..)

              【讨论】:

              • 编译错误? “你能设计出最短的程序编译,但执行时会立即崩溃吗?”
              • MMmmm,应该可以编译
              • 哦,老兄,现在你正在掌握技术。 :)
              • @Mark 和 leppie:该代码确实可以编译,正如perl -c 所验证的那样。该错误是运行时错误,Perl 只是帮助您识别程序中的位置。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-01-04
              • 2021-08-22
              • 2012-01-18
              • 1970-01-01
              • 1970-01-01
              • 2014-06-11
              • 2011-11-20
              相关资源
              最近更新 更多