问题
Why does byte-compiling the the following produce a warning?
(defmacro foomacro (shiftcode)
`(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)))
;; provide backward compatibility for Emacs 22
(if (fboundp 'handle-shift-selection)
(foomacro "^")
(foomacro ""))
This is the warning I get:
$ emacs -Q --batch --eval '(byte-compile-file "foo.el")'
In foomacro:
foo.el:1:21:Warning: value returned from (concat shiftcode "p") is unused
If I get rid of bar
, the warning goes away:
(defmacro foomacro (shiftcode)
`(defun foo (&optional arg)
(interactive ,(concat shiftcode "p"))
(message "arg is %i" arg)))
;; provide backward compatibility for Emacs 22
(if (fboundp 'handle-shift-selection)
(foomacro "^")
(foomacro ""))
I'm using GNU Emacs 24.2.1.
回答1:
That's because you forgot to wrap the macro body in a progn:
(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))))
Think about how macros work. When you call (foomacro "...")
, the lisp engine recognizes that foomacro
is a macro and expands it, i.e., calls it on the argument(s) supplied. the return value of the macro is, as expected, the second defun
form; while the first defun
form is discarded. Then the lisp engine evaluates the return value (which is the second defun
form). Thus in your progn
-less version only bar
is defined, not foo
.
To understand the process, you need to realise that macros are merely "code transformation" tools; they don't really do anything. Thus only their return values are seen by the compiler (or the interpreter).
来源:https://stackoverflow.com/questions/17073755/value-returned-is-unused-warning-when-byte-compiling-a-macro