Get rid of "reference to free variable" byte-compilation warnings

François Févotte picture François Févotte · Sep 14, 2012 · Viewed 14.6k times · Source

I'm writing an emacs major mode, which uses buffer-local variables to store some state:

(defun foo-mode ()
  "My nice major mode"
  (interactive)
  (kill-all-local-variables)
  (setq mode-name "foo")
  (setq major-mode 'foo-mode)
  (set (make-local-variable 'foo-state) "bar"))

(defun foo-change-state ()
  (setq foo-state "baz"))

This works very well and has the property that in any buffer not using my major mode, the foo-state variable is not bound (which is a good thing in my opinion, since it avoids cluttering the symbols table).

However, byte-compiling such a piece of code produces the following warning:

Warning: assignment to free variable `foo-state'

Using defvar gets rid of the warning, but has the side-effect that foo-state is now bound everywhere, which is undesirable in my opinion.

Is there a way to get rid of the warnings while still not binding the mode-specific variables in every buffer? Or am I mistaken when I think these variables should not be declared globally?

Answer

Stefan picture Stefan · Sep 15, 2012

The official way to do what you want is (defvar foo-state). Note the absence of a second argument. Note also that such a declaration only applies to the file where it is found (or to the scope in which it is found, if it's used inside a function).