Clisp";程序堆栈溢出。重置";在(cadr)上。怎么用?

Clisp";程序堆栈溢出。重置";在(cadr)上。怎么用?,lisp,common-lisp,stack-overflow,clisp,Lisp,Common Lisp,Stack Overflow,Clisp,我(仍然)在将代码从franzlisp移植到commonlisp。现在,我似乎把翻译推进了一个奇怪的角落,在那里它爆炸了 [11]> (setq fff (cadr contextstack)) *** - Program stack overflow. RESET 那怎么会导致堆栈溢出呢?递归在哪里 我可以选择长度确定: [12]> (length contextstack) 79 描述工作原理。这只是长时间“描述”输出的开始 [13]>(描述(cadr上下文堆栈))

我(仍然)在将代码从franzlisp移植到commonlisp。现在,我似乎把翻译推进了一个奇怪的角落,在那里它爆炸了

[11]> (setq fff (cadr contextstack))    
*** - Program stack overflow. RESET
那怎么会导致堆栈溢出呢?递归在哪里

我可以选择长度确定:

[12]> (length contextstack)
79
描述
工作原理。这只是长时间“描述”输出的开始

[13]>(描述(cadr上下文堆栈))
(#.#1=#)是一个缺点。
#这是一个解释
功能。
参数列表:(节点)
#1=#是ENODE类型的结构。
插槽:
爱洛特=
#1=#S(ENODE:EROOT#1#:EQCLASS#1#:ESUCCESSORS ALLTRUE!:ESLENGTH NIL:epredcessors NIL:econgrunt NIL:edememmon NIL:emergeedemon NIL
:EPATTERN
更多
但几乎所有应用于
contextstack
的其他内容都会出现堆栈溢出消息

结构
ENODE
包含指向其他
ENODE
项的链接,并且存在循环,这可能导致一些代码循环。但是
cadr
?这是怎么回事 甚至可能

最初的代码使用了“hunks”,这是一个1970年代的MacLISP特性。我将其转换为使用通用LISP结构,可能破坏了某些东西

这都是解释性的;我没有编译任何东西。安全级别是默认值。我尝试添加
(宣告“(优化(安全3)))
以强制进行更多检查,但它没有改变任何东西

如果要复制此代码,请下载中的代码

启动“clisp”,执行
(加载设置)
,然后开始查看
contextstack
。任何中断都会在程序初始化时提前发生。

您是如何得到错误的 很可能是打印时出错,而不是
cadr
。您可以通过

(progn (cadr contextstack) nil)
这应该很管用

如果它仍然爆炸,您应该检查
cadr
是否引发异常(然后错误消息将包含一个循环对象并爆炸):

如何避免错误 说:

当您尝试打印圆形对象(
LIST
STRUCTURE-object
VECTOR
等)且为
NIL
时,总是会出现堆栈溢出。只需将
*print-CIRCLE*
设置为
T

请注意,这不是特定于CLISP的,当
*print circle*
nil
时,任何ANSI Common Lisp都会出现相同的错误

在您的特定情况下,请仔细查看
(descripe(cadr contextstack))
的输出:

(#.#1=#)是一个缺点

是由 打印机,以避免打印圆形对象时堆栈溢出


附言:-)

对。发生的情况是,“cadr”应用于非列表,这会触发一条错误消息,试图打印一个循环列表,这会破坏堆栈。@JohnNagle:这实际上可以解释为CLISP中的一个错误:错误报告应该可以正常工作。这是一种错误。内置的漂亮打印机由中断触发,进入递归循环,不打印任何内容。然后它达到堆栈限制,整个堆栈被丢弃。因此,没有迹象表明问题是什么,堆栈已丢失。如果它在降低数据结构时打印了一些内容,或者在被中断触发时默认有一个长度限制,那么就很清楚发生了什么。这是糟糕的违约行为。但是clisp的上一个版本是在2010年,所以现在提交bug报告是没有意义的。
(progn (cadr contextstack) nil)
(and (consp contextstack)
     (consp (cdr contextstack)))