可笑的运行时错误


40

编写程序,这些程序会产生疯狂,晦涩,荒谬或仅仅是普通的运行时错误。不需要混淆和泛音(简短)。

  • 看起来应该可以正常工作的解决方案更好。
  • 看起来应该以一种方式打破但以另一种方式打破的解决方案更好。
  • 只要有时可以重现,则不确定的解决方案会更好。
  • 错误原因和表现形式之间的距离较长的解决方案更好。
  • 产生错误的奖励积分,这应该是不可能的。
  • 对于使运行时崩溃(例如使python段出错)或操作系统崩溃的错误的加分。

分数单位应为赞成票。

附录1

编译器的不良行为也可以。


2
使Python segfault变得容易:import sys; sys.setrecursionlimit(~-2**31); x=lambda x:x(x); x(x);
marinus 2012年

彼得:哎呀。我在写问题的一半时就改了这个问题:S
Wug,2012年

...恶意攻击或INTERCAL怎么办?我很确定他们会有一些非常疯狂的错误,也许也可以用一个字符做。
acolyte'Aug

1
这绝对是寻求该解决方案的最佳链接:destroyallsoftware.com/talks/wat :-)
seri 2012年

Answers:


69

强制性PHP一个(其仍然没有被固定为5.4):

<?::

输出:

解析错误:语法错误,第1行出现意外T_PAAMAYIM_NEKUDOTAYIM

aa?


12
我喜欢这个。这可能是我最喜欢的错误消息。除了一次我的朋友尝试将Windows笔记本电脑引导到恢复分区外,它还使整个屏幕变成了一个白色框,上面有大红色字母,拼写为“ ERROR”。
乌格2012年

4
故意但很奇怪:“起初,Paamayim Nekudotayim似乎是为双冒号命名的一个奇怪选择。但是,在编写Zend Engine 0.5(支持PHP 3)时,Zend团队决定将其命名为实际上,这确实意味着希伯来语是双冒号!” php.net/manual/en/language.oop5.paamayim-nekudotayim.php
乔恩·高

12
@HansEngel:是的,在希伯来语中是双冒号。除此令牌外,对每个令牌都使用英语是有意义的,因为...?我想我只需要问PHP团队。
2012年

抱歉,伙计,但您只是''从类''(空字符串)中调用静态方法/变量(空字符串)
Ismael Miguel 2014年

1
@IsmaelMiguel:这是因为希伯来语而令人困惑,而不是因为它是错误的。
2014年

61

Gcc编译错误:

int main()
{
        long long long a;
}

错误:long long long对于GCC来说太长了


6
他们只是知道有人会尝试long long long,如果longlong long都有效。
Konrad Borowski14年

3
我认为“太长了!” 本来是更好的错误消息,但这仍然是一个很好的答案。
Wug 2014年

52

Windows命令提示符

If you're happy and you know it clap your hands!

输出:

幸福在这个时候是始料未及的。


1
我尝试了该命令来检查结果,但是显示了^V:(辛苦了这些
Fabricio 2014年

8
@Fabricio,是否只是按CTRL + V粘贴行?在命令提示符下,键盘上的“快捷键”,用于粘贴是Alt +空格键,E,P
手工E-食品

42

的PHP

$ cat error.php 
<?php
function echo_string(string $string) {
    echo $string;
}
echo_string("Hello, world!");
$ php error.php 
PHP Catchable fatal error:  Argument 1 passed to echo_string() must be an instance of string, string given, called in error.php on line 5 and defined in error.php on line 2

您不能将字符串传递给函数,而必须传递字符串!

更新:该代码不是PHP 7中的错误。将鼠标悬停在/单击/触摸扰流板可以检查原因(包含扰流板有关代码的工作原理)。

PHP 7中添加了一个称为标量类型声明的新功能。此功能允许在函数声明中使用标量类型。


6
什么是F *** PHP。
Wug 2014年

7
PHP试图获取该类string(有效)。类型提示(您正在做的事情)仅适用于类。由于该类string不存在,因此会引发错误。
Ismael Miguel

您可以在此处检查您的代码是否正常工作:sandbox.onlinephpfunctions.com/code/…–
Ismael Miguel

2
@IsmaelMiguel:是的,我知道为什么会发生,但是我认为错误仍然很可笑。
Konrad Borowski

1
然后尝试array(''=>array()'')
Ismael Miguel

33

重击

$ echo "Hello, world!"
bash: !": event not found

而且您会认为bash会接受一个简单的“ Hello,world!”。程序。


对此的解释:扩展为bash中程序参数的双引号中传递的字符串,这意味着`echo hi`变成hi双引号字符串的内部。!用作事件指示符的前缀。因此,bash尝试评估!",但找不到引用的事件。
Mego

31

Python 2.7

# Look I'm actually coding: see my happy face?
print ':)'

产生相当无益的:

SyntaxError: encoding problem: with BOM

简单的注释如何产生错误?


12
在最新的Python解释器中:如果前两行以开头#并包含字符串,则coding:下一个单词用作编码描述
AMK 2014年

31

Mathematica

当使用Mathematica创建图形输出时,有时会触发错误消息,这些错误消息是根据程序本身使用的规范进行格式化的。这是一个简单的例子。

Rotate[f/0, .6]

在此处输入图片说明


11
但是,那并不是真正的错误消息,是吗?这只是Mathematica将某物除以零时返回的值。
Ilmari Karonen 2014年

26

TI-89图形计算器

我在学习高中微积分的隐式微分时发现了这一点。如果输入:

d(xy+x=0,x)

您得到以下信息:

1 = 0

使用此警告,在屏幕底部以小写字母打印:

Warning: May produce false equation

发生这种情况是因为xy不会解释为x * y,而是解释为它自己的符号xy

奇怪的是,如果这样做d(xy=0,x),您将得到0 = 0相同的警告。


22

您可以使Haskell编译器的大脑爆炸:

C:\Windows\system32>ghci
...
Prelude> :set -XExistentialQuantification
Prelude> data Foo = forall a. Foo a
Prelude> let foo f = 1 where Foo a = f

<interactive>:4:21:
    My brain just exploded
    I can't handle pattern bindings for existential or GADT data constructors.
    Instead, use a case-expression, or do-notation, to unpack the constructor.
    In the pattern: Foo a
    In a pattern binding: Foo a = f
    In an equation for `foo':
        foo f
          = 1
          where
              Foo a = f
Prelude>

22

红宝石

规管滥用行为。

class StandardError

  def to_s
    words = File.open('/usr/share/dict/words'){|f|f.readlines.map &:chop}.sample(100)
    words.last.capitalize!
    super.gsub(/\w+/){words.pop}
  end

  to_s(3)

end

如果在OSX上运行,则会产生例如

$ ruby weird_runtime_error.rb 
weird_runtime_error.rb:9:in `to_s': Sculpturation contingence explicate tappet(phonendoscope ethopoeia nannandrous) (ArgumentError)
    from weird_runtime_error.rb:9:in `<class:StandardError>'
    from weird_runtime_error.rb:1:in `<main>'

6
这到底是什么意思?
TRiG 2014年

9
这意味着wrong number of arguments(1 for 0)。它是通过使用英语词汇懒惰地随机产生的一种语言表达的,很少考虑语言的合理性。
历史学家2014年

21

DOS提示

c:\>make love

给你

Fatal Error: 'love' does not exist. Don't know how to make it.

我在尝试侮辱计算机不合作时偶然发现了这一点。让我有点难过,直到我发现,这只有在爱不存在的情况下才会发生。如果存在,他将很乐意做到。


5
这实际上专用于make实用程序,而不是DOS本身。
钒2014年

1
我得到:make: *** No rule to make target 'love'. Stop.
2015年

@agtoever您运行的品牌错误。
纳文,2015年

我明白了:make: Fatal error: Don't know how to make target 'love'但这是在Unix上。在DOS上,我得到了make is not recognized as an internal or external command, operable program or batch file
lebatsnok

17

重击(Quine错误)

此错误是Bash中的Quine!

$ bash: bash:: command not found...
bash: bash:: command not found...

当然,您必须具有相关的信息locale(在此处英语)。


1
我的没有...在末尾打印,所以我也不得不在原始输入中省略它。
Zev Eisenberg 2014年

16

CSH

一个非常经典的csh笑话:

% make fire?
make: No match.

15

Bash-准确再现罕见的历史错误消息

echo -ne $(tail -n +257 /usr/src/linux*/drivers/char/lp.c | head -1 | cut -d '"' -f 2 | sed 's/%d/0/')

输出:

lp0 on fire

需要在通常的地方解压缩linux内核源代码。

有趣的事实:运行一台旧的色带打印机时,我曾认真收到过此消息。


它是错误消息,还是程序的输出?
2015年

1
@yo'bash单行代码本身成功返回,但是它产生的输出是真正的错误消息;该脚本只是从打印机驱动程序源中提取错误。
暴动

嗯,那是一件棘手的事情:-)

1
顺便说一句,该错误表示它正在继续打印到卡纸,这有引发火灾的危险。
2015年

13

C(++)

如果编译时错误在这里算是一个(假设文件名为“ crash.c”)。

#include "crash.c"

int main(){ return 0; }

编译时将其填满屏幕(已准备好Ctrl-C)

                 from crash.c:1,
                 from crash.c:1:
crash.c:3:1: error: redefinition of ‘main’
crash.c:3:1: note: previous definition of ‘main’ was here
In file included from crash.c:1:0,
                 from crash.c:1,
                 from crash.c:1,

另一个可完美编译的代码段(下面没有警告,-Wall并说明了C的优美类型安全性</ s>

#include <stdio.h>
int i;

int main(){
  sprintf(NULL, "%s", (char *) (void *) (1/i));
  return 0;
}

运行它可以得到:

Floating point exception (core dumped)

13

红宝石

觉得这可能是一种高级语言,这很奇怪。

$*<<$*<<$**$/

产生

ArgumentError: recursive array join

10

这很老了,但是对于那些记得BCPL的人来说,

GET "LIBHDR"

LET START() = VALOF 
$8
        RESULTIS 0
$)

会抱怨

$8
 ^
"( ) or 8 expected"

10

[R

从技术上讲,这不是错误,而是警告,但仍然很荒谬,并且出于完全深奥的原因而发生。

[[编辑]]似乎某些有趣警告的原因在于RStudio,而不是R本身,所以它比我最初想象的要有趣。plot(1:2, NotAGraphicalParameter = "ignore.me")但是,第一个示例仍然可以在“裸” R中重现,并且就其本身而言很有趣。[[/ EDIT]]

> plot(1:2, NotAGraphicalParameter = "ignore.me")
# produces a nice scatterplot with two points, [1,1] and [2,2]
Warning messages:
1: In plot.window(...) :
  "NotAGraphicalParameter" is not a graphical parameter
2: In plot.xy(xy, type, ...) :
  "NotAGraphicalParameter" is not a graphical parameter
3: In axis(side = side, at = at, labels = labels, ...) :
  "NotAGraphicalParameter" is not a graphical parameter
4: In axis(side = side, at = at, labels = labels, ...) :
  "NotAGraphicalParameter" is not a graphical parameter
5: In box(...) : "NotAGraphicalParameter" is not a graphical parameter
6: In title(...) : "NotAGraphicalParameter" is not a graphical parameter
> plot(2:3)
# another nice scatterplot: [2,2] and [3,3] 
# but there should be nothing wrong this time!
# however ...
There were 12 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: "NotAGraphicalParameter" is not a graphical parameter
2: "NotAGraphicalParameter" is not a graphical parameter
3: "NotAGraphicalParameter" is not a graphical parameter
4: "NotAGraphicalParameter" is not a graphical parameter
5: "NotAGraphicalParameter" is not a graphical parameter
6: "NotAGraphicalParameter" is not a graphical parameter
7: "NotAGraphicalParameter" is not a graphical parameter
8: "NotAGraphicalParameter" is not a graphical parameter
9: "NotAGraphicalParameter" is not a graphical parameter
10: "NotAGraphicalParameter" is not a graphical parameter
11: "NotAGraphicalParameter" is not a graphical parameter
12: "NotAGraphicalParameter" is not a graphical parameter
# but let's try once more:
> plot(2:3)
# yup. no warnings this time. we had to do it twice

就像R记得我们的侮辱一样。但不长久。

我无法真正解释为什么会发生这种情况-但它是可重复的。实际上,每当您为图1提供一些“非图形参数”然后以完全无可挑剔的方式进行图2时,就会发生这种情况。特别有趣的是,第二个图得到12个“非图形参数”警告,而第一个图只有6个。另一个有趣的事情是,如果您提供的“非图形参数”值为NULL,则不会引发任何条件:

plot(1:2, Nonsense=NULL)
# no warnings
# however
plot(1:2, Nonsense="gibberish")
# gives the usual 6-pack of warnings

为了更加荒谬,让我们在先前绘制的图上绘制一些线条:

plot(1:2)
# you will see the number of warnings growing with each line:
lines(1:2, 1:2, mumbo = 1)
lines(1:2, 1:2, jumbo = 2)
lines(1:2, 1:2, bimbo = 3)
lines(1:2, 1:2, cucaracha = 4)
lines(1:2, 1:2, karaoke = 5)
lines(1:2, 1:2, radiogaga = 6)
lines(1:2, 1:2, reptiles = 7)
lines(1:2, 1:2, cowsonmoon = 8)
lines(1:2, 1:2, stainlessSteelLadderToTheMoon = 9)
lines(1:2, 1:2, frambuesa = 10)
lines(1:2, 1:2, fresa = 11)
lines(1:2, 1:2, limonYNada = 12)
lines(1:2, 1:2, slingsAndArrows = 13)
# ... and now you have 25 warnings:
warnings()

Warning messages:
1: "mumbo" is not a graphical parameter
2: "jumbo" is not a graphical parameter
3: "bimbo" is not a graphical parameter
4: "cucaracha" is not a graphical parameter
5: "karaoke" is not a graphical parameter
6: "radiogaga" is not a graphical parameter
7: "reptiles" is not a graphical parameter
8: "cowsonmoon" is not a graphical parameter
9: "stainlessSteelLadderToTheMoon" is not a graphical parameter
10: "frambuesa" is not a graphical parameter
11: "fresa" is not a graphical parameter
12: "limonYNada" is not a graphical parameter
13: "mumbo" is not a graphical parameter
14: "jumbo" is not a graphical parameter
15: "bimbo" is not a graphical parameter
16: "cucaracha" is not a graphical parameter
17: "karaoke" is not a graphical parameter
18: "radiogaga" is not a graphical parameter
19: "reptiles" is not a graphical parameter
20: "cowsonmoon" is not a graphical parameter
21: "stainlessSteelLadderToTheMoon" is not a graphical parameter
22: "frambuesa" is not a graphical parameter
23: "fresa" is not a graphical parameter
24: "limonYNada" is not a graphical parameter
25: In plot.xy(xy.coords(x, y), type = type, ...) :
  "slingsAndArrows" is not a graphical parameter

这应该除非没有正义,否则就赢得大笔时间。


1
您正在使用哪个版本的R?因为我无法重现你用得到警告的包装plot(2:3)使用之后plot(1:2, NotAGraphicalParameter = "ignore.me")。您重新定义了您的东西.Rprofile吗?
plannapus 2014年

1
看起来这是特定于Rstudio(在Windows和Ubuntu上)运行R的,但是在Linux终端或Windows Rgui中运行R时不会发生。
lebatsnok

我想我在没有Rstudio的情况下已经看到了与建模函数(lm或glm)相似的东西,但现在无法重现。(也就是说,当不再
有用

9

Windows命令脚本

警告,这是叉子炸弹!

如果您尝试以任何方式退出控制台,这将输出有关退出的垃圾问题。

%0|%0|%0

奖金:

  • 直到重新启动将使系统几乎无法使用
  • 防止退出脚本,这应该是不可能的

2
危险鲁滨逊会吗?
2014年


6

编译器优化错误如何:

#include <stdio.h>

#define N 4

int main(void)
{
    int sum;
    int i;
    int arr[N];

    for (i = 0, sum = 0; i < N; i++, arr[i] = sum) {
        sum += arr[i];
    }
    printf("%d\n", sum);
    return 0;
}

这特定于gcc> = 4.7。使用编译并正常运行gcc -O0 -Wall。与一起编译,gcc -O2 -Wall但会导致inf循环。

还要注意,gcc如何看到更小的问题N,例如N = 3

test.c:11:38: warning: array subscript is above array bounds [-Warray-bounds]
  for (i = 0, sum = 0; i < N; i++, arr[i] = sum) {
                                       ^
test.c:12:13: warning: 'arr[0]' is used uninitialized in this function [-Wuninitialized]
  sum += arr[i];
         ^

顺便说一句,这是从一个错误报告中摘录的,尽管我不记得这个错误号。


3
好吧,这是未定义的行为,因此允许编译器执行任何操作。但是,仍然感到奇怪的是,编译器决定更改从未使用的局部数组之外的赋值,并将未声明的值用于无限循环,即使C标准允许这样做(毕竟,这取决于未定义的行为-访问arr[N](数组外部)和访问arr[0](未初始化))。由于未定义的行为允许做任何事情,因此这不是优化错误,但极不可能是用户想要的。
Konrad Borowski14年

4
显然不是编译器优化错误。UB是UB,即使编译器决定清除硬盘中的所有数据,编译器也将是正确的。
H2CO3

5

我一直喜欢APL中的这种怪异之处:

      ⍝显然是语法错误
      {(]} 3  
语法错误
      {(]} 3

      ⍝但是:
      {(]} 1÷0
域错误
      {(]} 1÷0 

      even它甚至可以与静态定义的函数一起使用
      ∇z←fx
[1] z←[{]} x
[2]∇
      f 1÷0
域错误
      f 1÷0
     ∧
      f 3
语法错误
f [1] z←[{]} x     

它懒散地解析函数内部!


4

的PHP

<?php
[][] = 42;

[]用于推送元素。但是,如果将它用于数组文字,PHP会发出疯狂的错误消息,即使您为了推送而分配了它。要求PHP> = 5.4,因为之前没有索引数组文字。

输出:

致命错误:无法使用[]来读取第2行的[...] [...]


4

蟒蛇

嵌套块

for a in range(26):
 for b in range(26):
  for c in range(26):
   for d in range(26):
    for e in range(26):
     for f in range(26):
      for g in range(26):
       for h in range(26):
        for i in range(26):
         for j in range(26):
          for k in range(26):
           for l in range(26):
            for m in range(26):
             for n in range(26):
              for o in range(26):
               for p in range(26):
                for q in range(26):
                 for r in range(26):
                  for s in range(26):
                   for t in range(26):
                    for u in range(26):
                     for v in range(26):
                      for w in range(26):
                       for x in range(26):
                        for y in range(26):
                         for z in range(26):
                          print a

Python 2.7: SystemError: too many statically nested blocks

自引用列表

def printList(myList):
    for element in myList:
        if isinstance(element, list):
            printList(myList)
        else:
            print(element)

a = []
a.append(a)
printList(a)

Python 2.7

真不是一个常数

以下示例中的问题是Python 2.7中的问题,True并且False不是常量。并且TrueFalse可以自动转换为10

True=False
a=10/True

Traceback (most recent call last):
  File "/home/moose/.config/pluma/tools/new-tool-2", line 11, in <module>
    exec(sys.stdin.read())
  File "<string>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero

Python 2.7:

意向

def f(n):
    if n <= 1:
        return n
    else:
        return f(n-1)+f(n-2)

你得到错误了吗?

Traceback (most recent call last):
  File "/home/moose/.config/pluma/tools/new-tool-2", line 11, in <module>
    exec(sys.stdin.read())
  File "<string>", line 4
    else:
       ^
SyntaxError: invalid syntax

在Python 2.7中可以混用制表符和空格...但是要注意缩进级别!


1
混合空间和制表符示例无法正常工作,因为Stack Exchange平台不允许代码中使用制表符。
Konrad Borowski14年

@xfix:好的,但是我认为读过这篇文章的人很明白。大多数编辑器也不显示空格/制表符(尾随空格除外),如果显示,则大多数情况下都是灰色的。并且在其他所有语言中(空格除外),只要没有至少一个空格,空格都不重要。
Martin Thoma 2014年

您应该使用Whitespace编程语言编写程序。
亚历山大

Python 3是个玩笑吗?
2014年

@minitech我不知道。那就是应该做的print a
贾斯汀

3

我将开始:

#include <iostream>

using namespace std;

class A
{
public:
    A()
    {
    }

    void doSomethingDiabolical()
    {
        delete this;
    }

    virtual void breakHorribly()
    {
        cout << "still alive" << endl;
        doSomethingDiabolical();
        cout << "still alive" << endl;
    }
};

class B : public A
{
public:
    B() : A()
    {
    }

    void breakHorribly()
    {
        cout << "still alive" << endl;
        ((A *) this)->breakHorribly();
        cout << "still alive" << endl;
        doSomethingDiabolical();
        cout << "still alive" << endl;
        breakHorribly();
        cout << "dead" << endl;
    }
};

int main()
{
    jane();
}

void jane()
{
    cout << "still alive" << endl;
    A * o = new B;
    cout << "still alive" << endl;
    o->breakHorribly();
}

任何猜测为什么该程序会崩溃?:D

参见jane运行:http//ideone.com/gtaZ3


1
这不是一个相当简单的无限递归吗?B::BreakHorriblydoSomethingDiabolical被调用之前先调用自身,所以delete this永远不会达到。
marinus 2012年

该程序由于多种原因而爆炸。如果删除其他打印语句,其行为会更改。但是,你是对的。我没有时间重现一次曾经的未定义行为,但是最终在运行时得到了一个纯虚函数调用。
Wug 2012年

2
您并不是说您曾经不小心输入了类似的字词delete this,对吗?

不,它比这要微妙得多,但是最终结果是相同的:在执行成员函数期间调用了一个析构函数的类
Wug,2012年

3

重击

今天,当我试图找出是否有可能保护系统免受感染时,我得到了这一信息rm -rf /

mkdir /tmp/a
mkdir /tmp/a/b
sudo mount --bind /tmp/a /tmp/a/b
rm -rf /tmp/a

错误消息LANG=C

rm: WARNING: Circular directory structure.
This almost certainly means that you have a corrupted file system.
NOTIFY YOUR SYSTEM MANAGER.
The following directory is part of the cycle:
  '/tmp/a/b'

此警告来自rm,不是bash。鉴于您曾经bash设置过标题,因此不确定在标题中应声明哪种语言。

2

[R

另一个不是很荒谬的警告,而不是错误,但仍然很不错:

> sapply(as.list(-1:-51), log)
 [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[20] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[39] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
There were 50 or more warnings (use warnings() to see the first 50)

我喜欢最后一点:50个或更多:)

以及实际的警告:

1: In lapply(X = X, FUN = FUN, ...) : NaNs produced
2: In lapply(X = X, FUN = FUN, ...) : NaNs produced
....
50: In lapply(X = X, FUN = FUN, ...) : NaNs produced

好玩=好玩!


1
Nyan代码?!好吧,那确实很奇怪!
Kroltan 2014年

我看不出有什么意外或惊奇的地方。负数的对数会产生应有的非数字(NaN)。
plannapus 2014年

2

CPython的

import ctypes
import sys
(ctypes.c_char * sys.getsizeof(None)).from_address(id(None))[:4] = '\x00' * 4

结果:

Fatal Python error: deallocating None

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

在Python 3中甚至更好ctypes.pythonapi._Py_Dealloc(ctypes.py_object(None))
kirbyfan64sos

2

重击-违反直觉的逃生失败

echo "this should definitely work!!!11!"

退货

-bash: !11: event not found

(用双引号不能阻止命令行上的历史记录扩展)

奖金:

echo "I don't know what's gone wrong!! !echo is usually pretty foolproof!-1"

输出不太可能达到预期。向上按以再次获取命令,并注意它与您键入的内容已更改。如果您按两次并输入几次,您的输出可能会看起来有些恐怖。自己尝试一下。


2
这个答案是codegolf.stackexchange.com/a/17776的副本。
丹尼斯

2

C#-递归,惰性斐波那契生成器

static void Main()
{
    Console.WriteLine(string.Join(",", fib().Take(141)));
    Console.ReadLine();
}

static IEnumerable<decimal> fib(decimal n = 0, decimal m = 1)
{
    if (n == 0)
    {
        yield return 0;
        yield return 1;
    }
    while (true)
    {
        yield return n + m;
        foreach(var x in fib(m, n+m))
        {
            yield return x;
        }
    }
}

这段代码看起来不错,对吧?一个相当简单的斐波那契生成器,增加了一些递归和惰性枚举。应该管用。

不!运行此命令将导致OverflowException。这是因为我们使用的是十进制,并且第141个斐波那契数(〜8.1E28)超过了十进制的最大值(〜7.9E28)。

但是,当您超过其最大值时,该int不会引发OverflowException。取而代之的是,它溢出到负值。因此,如果我们将int替换为十进制,如下面的代码所示,它应该可以工作,对吧?

static void Main()
{
    Console.WriteLine(string.Join(",", fib().Take(141)));
    Console.ReadLine();
}

static IEnumerable<int> fib(int n = 0, int m = 1)
{
    if (n == 0)
    {
        yield return 0;
        yield return 1;
    }
    while (true)
    {
        yield return n + m;
        foreach(var x in fib(m, n+m).ToList())
        {
            yield return x;
        }
    }
}

如果您阅读了该代码,则很明显为什么这行不通。如果您没有...我不只是将类型从十进制更改为整数;我也偷偷了foreach语句中对ToList()的调用。这将强制对返回的枚举数进行紧急评估。这将不会导致141次递归,而是会导致无限次递归。实际上,很久很久之前,它当然会溢出堆栈,从而导致运行时引发StackOverflowException。(奖励:无法捕获此异常,因此它将使运行时崩溃)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.