【发布时间】:2016-11-28 04:03:09
【问题描述】:
我将收到关于 SBCL 中 f2 的未定义函数警告,并带有以下代码示例。 是否可以像在 C 中一样首先声明 f2 以避免警告。 我用谷歌搜索,没有任何线索。
(defun f ()
(print (f2)))
(defun f2 ()
(print "f2"))
【问题讨论】:
标签: lisp common-lisp
我将收到关于 SBCL 中 f2 的未定义函数警告,并带有以下代码示例。 是否可以像在 C 中一样首先声明 f2 以避免警告。 我用谷歌搜索,没有任何线索。
(defun f ()
(print (f2)))
(defun f2 ()
(print "f2"))
【问题讨论】:
标签: lisp common-lisp
【讨论】:
(load (compile-file "file.lisp")),或者从 Slime/Sly 中使用 C-c C-k。
如果函数在同一个文件中,编译器不会给出警告。
SBCL 示例:
bash-3.2$ sbcl
This is SBCL 1.3.10, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (compile-file "/tmp/order.lisp")
; compiling file "/private/tmp/order.lisp" (written 28 NOV 2016 12:14:37 PM):
; compiling (DEFUN F ...)
; compiling (DEFUN F2 ...)
; /tmp/order.fasl written
; compilation finished in 0:00:00.178
#P"/private/tmp/order.fasl"
NIL
NIL
* (load *)
T
*
【讨论】:
您不必将函数放入 Common Lisp 中的同一个文件中,以便它们位于同一个编译单元中。
这样做是一种反模式;当然,大型程序是由模块构成的,其中大多数调用另一个模块中的函数。您不能将整个程序滚动到单个物理模块中以避免出现警告。
Lisp 有一种机制,可以将一组编译器视为一个编译单元:with-compilation-unit 宏:
(with-compilation-unit
(compile-file "file-f")
(compile-file "file-f2"))
如果您使用 ASDF 构建系统,我似乎记得它在后台为您执行 with-compilation-unit,围绕系统的所有文件。
这种方法将有助于消除那些被延迟的警告。也就是说,如果实现警告未定义的标识符,但 defers 这样做直到编译单元结束,那么如果使用此宏,则延迟会延长到总编译结束单元跨越多个文件。
当有关未定义标识符的警告被延迟时,目的是消除这些警告。如果先前未定义的函数的定义出现在翻译单元的结尾之前,则可以抑制警告。此宏允许一个文件中的定义抑制另一个文件中的延迟警告。
如果实现不延迟警告,则宏将无济于事。
【讨论】:
with-compilation-unit 会将延迟扩展到多个文件。实现延迟警告正是为了消除不必要的警告。如果在编译单元结束之前看到函数的定义,则延迟的“未定义函数”警告会自动消失。
只需更改您的 defun 的顺序。首先,定义 f2 和大于 f。
【讨论】: