Emacs &引用;返回的值为“未使用”;编译宏时出现警告

Emacs &引用;返回的值为“未使用”;编译宏时出现警告,emacs,elisp,compiler-warnings,emacs24,Emacs,Elisp,Compiler Warnings,Emacs24,为什么编译下面的字节会产生警告 (defmacro-foomacro(shiftcode) `(defun foo(&可选参数) (交互式,(concat shiftcode“p”)) (消息“arg是%i”arg)) `(解除锁定栏(&可选参数) (交互式,(输入一个数字:)) (消息“arg是%i”arg))) ;; 为Emacs 22提供向后兼容性 (如果(fboundp’手柄移位选择) (详情请参阅会议过程正式纪录英文本) (foomacro“)) 这是我得到的警告: $emacs-Q

为什么编译下面的字节会产生警告

(defmacro-foomacro(shiftcode)
`(defun foo(&可选参数)
(交互式,(concat shiftcode“p”))
(消息“arg是%i”arg))
`(解除锁定栏(&可选参数)
(交互式,(输入一个数字:))
(消息“arg是%i”arg)))
;; 为Emacs 22提供向后兼容性
(如果(fboundp’手柄移位选择)
(详情请参阅会议过程正式纪录英文本)
(foomacro“))
这是我得到的警告:

$emacs-Q--batch--eval'(字节编译文件“foo.el”)'
在foomacro中:
foo.el:1:21:警告:从(concat shiftcode“p”)返回的值未使用
如果我清除了
,警告就会消失:

(defmacro-foomacro(shiftcode)
`(defun foo(&可选参数)
(交互式,(concat shiftcode“p”))
(消息“arg是%i”arg)))
;; 为Emacs 22提供向后兼容性
(如果(fboundp’手柄移位选择)
(详情请参阅会议过程正式纪录英文本)
(foomacro“))

我使用的是GNU Emacs 24.2.1。

这是因为您忘记在程序中包装宏体:

(defmacro foomacro (shiftcode)
  `(progn
     (defun foo (&optional arg)
       (interactive ,(concat shiftcode "p"))
       (message "arg is %i" arg))
     (defun bar (&optional arg)
       (interactive ,(concat shiftcode "Nenter a number: "))
       (message "arg is %i" arg))))
想想宏是如何工作的。调用
(foomacro“…”
时,lisp引擎会识别出
foomacro
是一个宏并将其展开,即根据提供的参数调用它。宏的返回值与预期一样是第二个
defun
表单;而第一个
defun
表单被丢弃。然后lisp引擎计算返回值(这是第二个
defun
表单)。因此,在您的
progn
中,只定义了
bar
,而不是
foo


要理解这个过程,您需要认识到宏仅仅是“代码转换”工具;他们什么都不做。因此,编译器(或解释器)只能看到它们的返回值。

为什么需要将宏体包装在
progn
中?
defmacro
的文档说明
BODY…
表示可以接受多个BODY表单。它还与
progn
的文档相匹配。。。我想我对宏观扩张的理解不像我想的那样。我问了一个后续问题:一旦我明白了这一点,我就应该能够理解多种身体形态是如何运作的。我现在明白了。非常感谢。