3

以下をバイトコンパイルすると警告が表示されるのはなぜですか?

(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 ""))

これは私が得る警告です:

$ emacs -Q --batch --eval '(byte-compile-file "foo.el")'

In foomacro:
foo.el:1:21:Warning: value returned from (concat shiftcode "p") is unused

を取り除くとbar、警告は消えます:

(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 ""))

GNU Emacs 24.2.1 を使用しています。

4

1 に答える 1

6

これは、マクロ本体を 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))))

マクロがどのように機能するかを考えてみましょう。を呼び出すと、Lisp エンジンはそれがマクロである(foomacro "...")ことを認識して展開します。つまり、指定された引数でそれを呼び出します。マクロの戻り値は、予想どおり2 番目の形式です。最初のフォームは破棄されます。次に、lisp エンジンは戻り値 ( 2 番目の形式) を評価します。したがって、あなたの-less バージョンでは、 ではなく のみが定義されています。foomacro defun defun defunprognbarfoo

このプロセスを理解するには、マクロが単なる「コード変換」ツールであることを理解する必要があります。彼らは本当に何もしません。したがって、それらの戻り値のみがコンパイラ (またはインタプリタ) によって認識されます。

于 2013-06-13T02:31:47.703 に答える