gpt4 book ai didi

common-lisp - SBCL 特定声明

转载 作者:行者123 更新时间:2023-12-02 21:51:47 24 4
gpt4 key购买 nike

SBCL 生成有关未定义函数的虚假样式警告。 (函数已定义,就在文件的后面。)我想一劳永逸地解决这个问题。幸运的是,有一种方法可以做到这一点:

(declaim (sb-ext:muffle-conditions style-warning))

缺点是,出于显而易见的原因,CCL 对包含上述内容的程序表示拒绝。我尝试用条件来解决这个问题:

(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))

但现在 SBCL 很不高兴:“非法函数调用”。

如何将这样的声明放入可移植程序中?

最佳答案

请注意,虽然现有答案是正确的,但禁用警告并不是一个好的做法。就您而言,可能没有必要。

Common Lisp 有一个编译单元的概念,其中多个定义被分组在一起。这使编译器/解释器有机会处理函数之间的交叉引用(例如,解释器可以收集警告并仅保留以后找不到的警告)。

例如,在文件#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))))

评估整个 block 不会显示 *EVALUATOR-MODE*:COMPILE:INTERPRET 的警告。

当您依次评估每个表达式(或者可能是一个区域又一个区域)时,您所目睹的情况会发生。在那里,编译器无法知道该函数已经存在。使警告静音是更糟糕的选择,因为您实际上可能犯了一个错误。

如果您事先知道某个函数存在,但不在您的编译单元中(也许它仅在运行时定义),那么您可以声明这一事实,如下:

(declaim (ftype function my-function))

上面说 my-function 必须被假定为 fboundfunction 类型的对象。您还可以通过细化您声称的功能类型来提供更多信息:

(declaim (ftype (function (number) (values string &optional)) num-to-string))

...对于接受数字并返回一个值(字符串)的函数。

(declaim (ftype (function () nil) forever-loop))

...对于不接受任何内容并且从不返回值(循环或发出错误信号)的函数。

关于common-lisp - SBCL 特定声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52300423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com