SBCL 特定声明
SBCL-specific declaim
SBCL 生成关于未定义函数的虚假样式警告。 (函数已定义,就在文件的后面。)我想一劳永逸地解决这个问题。幸运的是,有一种方法可以做到这一点:
(declaim (sb-ext:muffle-conditions style-warning))
缺点是 CCL,出于显而易见的原因,拒绝包含上述内容的程序。我尝试用条件解决这个问题:
(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
但现在SBCL不开心:"illegal function call".
如何将这样的声明放入可移植程序中?
省略外面的一对括号:
#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
当您使用 declaim
时,我假设声明出现在编译单元的顶层。如果您需要对多个顶级语句进行分组,您可以用 progn
将它们全部包装起来(这不会改变 "top-level"-ness)。
SBCL 抱怨的原因是,它的 reader 读取
((declaim (sb-ext:muffle-conditions style-warning)))
(因为存在 :SBCL
功能),这只是一个语法错误。 CCL不抱怨,因为其reader读
()
这只是 nil
.
的另一种拼写方式
请注意,虽然现有答案是正确的,但禁用警告并不是一个好的做法。在您的情况下,可能没有必要。
Common Lisp 有一个编译单元的概念,多个定义组合在一起。这让 compiler/interpreter 有机会处理函数之间的交叉引用(例如,解释器可以收集警告并仅保留那些以后找不到的警告)。
例如,在文件 #P"/tmp/foo.pl"
中:
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
不评估文件中的任何内容;而是做:
(compile-file #P"/tmp/foo.pl")
; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)
; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
没有警告。然后您可以调用 (load #P"/tmp/foo.fasl")
以在您当前的 lisp 环境中获得定义,而不会出现警告。
通常,ASDF 和扩展名 Quicklisp 使用 COMPILE-FILE
,因此只要将文件捆绑到系统中,您的问题就会消失。
您还可以这样做:
(with-compilation-unit ()
(defun mut-rec-foo/bis (x)
(when (plusp x)
(mut-rec-bar/bis (1- x))))
(defun mut-rec-bar/bis (x)
(print x)
(mut-rec-foo/bis (1- x))))
评估整个块不会显示 *EVALUATOR-MODE*
是 :COMPILE
或 :INTERPRET
。
的警告
当你一个接一个地计算每个表达式(或者一个区域接一个区域)时,你所看到的就会发生。在那里,编译器无法知道函数已经存在。使警告静音是更糟糕的选择,因为您实际上可能犯了错误。
如果你事先知道一个函数 将 存在,但不在你的编译单元中(也许它只在运行时定义),你可以 declaim那个事实,如下:
(declaim (ftype function my-function))
上面说 my-function
必须被假定为 fbound
到 function
类型的对象。您还可以通过细化您声称的函数类型来提供更多信息:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
... 对于接受数字且 return 恰好是一个值(字符串)的函数。
(declaim (ftype (function () nil) forever-loop))
... 对于不接受任何内容且从不接受 return 值(循环或发出错误信号)的函数。
SBCL 生成关于未定义函数的虚假样式警告。 (函数已定义,就在文件的后面。)我想一劳永逸地解决这个问题。幸运的是,有一种方法可以做到这一点:
(declaim (sb-ext:muffle-conditions style-warning))
缺点是 CCL,出于显而易见的原因,拒绝包含上述内容的程序。我尝试用条件解决这个问题:
(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
但现在SBCL不开心:"illegal function call".
如何将这样的声明放入可移植程序中?
省略外面的一对括号:
#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
当您使用 declaim
时,我假设声明出现在编译单元的顶层。如果您需要对多个顶级语句进行分组,您可以用 progn
将它们全部包装起来(这不会改变 "top-level"-ness)。
SBCL 抱怨的原因是,它的 reader 读取
((declaim (sb-ext:muffle-conditions style-warning)))
(因为存在 :SBCL
功能),这只是一个语法错误。 CCL不抱怨,因为其reader读
()
这只是 nil
.
请注意,虽然现有答案是正确的,但禁用警告并不是一个好的做法。在您的情况下,可能没有必要。
Common Lisp 有一个编译单元的概念,多个定义组合在一起。这让 compiler/interpreter 有机会处理函数之间的交叉引用(例如,解释器可以收集警告并仅保留那些以后找不到的警告)。
例如,在文件 #P"/tmp/foo.pl"
中:
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
不评估文件中的任何内容;而是做:
(compile-file #P"/tmp/foo.pl")
; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)
; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
没有警告。然后您可以调用 (load #P"/tmp/foo.fasl")
以在您当前的 lisp 环境中获得定义,而不会出现警告。
通常,ASDF 和扩展名 Quicklisp 使用 COMPILE-FILE
,因此只要将文件捆绑到系统中,您的问题就会消失。
您还可以这样做:
(with-compilation-unit ()
(defun mut-rec-foo/bis (x)
(when (plusp x)
(mut-rec-bar/bis (1- x))))
(defun mut-rec-bar/bis (x)
(print x)
(mut-rec-foo/bis (1- x))))
评估整个块不会显示 *EVALUATOR-MODE*
是 :COMPILE
或 :INTERPRET
。
当你一个接一个地计算每个表达式(或者一个区域接一个区域)时,你所看到的就会发生。在那里,编译器无法知道函数已经存在。使警告静音是更糟糕的选择,因为您实际上可能犯了错误。
如果你事先知道一个函数 将 存在,但不在你的编译单元中(也许它只在运行时定义),你可以 declaim那个事实,如下:
(declaim (ftype function my-function))
上面说 my-function
必须被假定为 fbound
到 function
类型的对象。您还可以通过细化您声称的函数类型来提供更多信息:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
... 对于接受数字且 return 恰好是一个值(字符串)的函数。
(declaim (ftype (function () nil) forever-loop))
... 对于不接受任何内容且从不接受 return 值(循环或发出错误信号)的函数。