如何查看Common Lisp内联函数展开?确认内联的方法有哪些?
如何查看Common Lisp中内联函数的展开?
先看你给出的示例代码:
(declaim (inline myinlinefunc)) (defun myinlinefunc (a) (* a 2)) (defun myglobalfunc (z) (+ (myinlinefunc z) 3)) CL-USER> (trace myinlinefunc myglobalfunc) (MYINLINEFUNC MYGLOBALFUNC) CL-USER> (myglobalfunc 2) 0: (MYGLOBALFUNC 2) 0: MYGLOBALFUNC returned 7 7 (3 bits, #x7, #o7, #b111)
从trace的输出看不到myinlinefunc的调用记录,确实能说明它已经被内联到myglobalfunc里,但追踪绝对不是唯一的确认方法。
如果你想直接看到内联展开后的myglobalfunc代码(类似宏展开的效果),不同Common Lisp实现有各自的工具:
SBCL:
- 开启编译打印选项,编译时就能看到展开后的代码:
输出里会显示内联替换后的中间代码。(setf sb-ext:*compile-print* t) (compile 'myglobalfunc) - 使用反汇编查看最终生成的代码,能直观看到内联后的逻辑:
(disassemble 'myglobalfunc) - 用
sb-cltl2:macroexpand-all展开整个函数定义,能看到内联替换后的形式:(sb-cltl2:macroexpand-all '(defun myglobalfunc (z) (+ (myinlinefunc z) 3)))
- 开启编译打印选项,编译时就能看到展开后的代码:
Clozure CL (CCL):
- 编译时开启 verbose 模式查看展开:
(compile-file "你的文件.lisp" :verbose t) - 反汇编查看最终代码:
(ccl:disassemble 'myglobalfunc)
- 编译时开启 verbose 模式查看展开:
通用技巧:
先设置优化级别保留调试信息,再查看展开,避免编译器过度优化导致信息丢失:(declaim (optimize (debug 3) (speed 0)))
简单来说,除了trace,你可以通过查看编译输出、反汇编代码、专用的编译器展开工具来确认内联并看到替换后的代码逻辑。
内容的提问来源于stack exchange,提问作者Jérôme Radix
相关产品推荐
相关产品推荐

