Byte-compiling a file often produces warnings about functions that the compiler doesn’t know about (see Compiler Errors). Sometimes this indicates a real problem, but usually the functions in question are defined in other files which would be loaded if that code is run. For example, byte-compiling simple.el used to warn:
simple.el:8727:1:Warning: the function ‘shell-mode’ is not known to be defined.
shell-mode is used only in a function that executes
(require 'shell) before calling
shell-mode will be defined properly at run-time. When you know
that such a warning does not indicate a real problem, it is good to
suppress the warning. That makes new warnings which might mean real
problems more visible. You do that with
All you need to do is add a
declare-function statement before the
first use of the function in question:
(declare-function shell-mode "shell" ())
This says that
shell-mode is defined in shell.el (the
‘.el’ can be omitted). The compiler takes for granted that that file
really defines the function, and does not check.
The optional third argument specifies the argument list of
shell-mode. In this case, it takes no arguments
nil is different from not specifying a value). In other
cases, this might be something like
(file &optional overwrite).
You don’t have to specify the argument list, but if you do the
byte compiler can check that the calls match the declaration.
Tell the byte compiler to assume that function is defined in the
file file. The optional third argument arglist is either
t, meaning the argument list is unspecified, or a list of
formal parameters in the same style as
defun (including the
parentheses). An omitted arglist defaults to
nil; this is atypical behavior for omitted arguments, and it
means that to supply a fourth but not third argument one must specify
t for the third-argument placeholder instead of the usual
nil. The optional fourth argument fileonly
nil means check only that file exists, not that it
actually defines function.
To verify that these functions really are declared where
declare-function says they are, use
to check all
declare-function calls in one source file, or use
check-declare-directory check all the files in and under a
These commands find the file that ought to contain a function’s
locate-library; if that finds no file, they
expand the definition file name relative to the directory of the file
that contains the
You can also say that a function is a primitive by specifying a file name ending in ‘.c’ or ‘.m’. This is useful only when you call a primitive that is defined only on certain systems. Most primitives are always defined, so they will never give you a warning.
Sometimes a file will optionally use functions from an external package.
If you prefix the filename in the
declare-function statement with
‘ext:’, then it will be checked if it is found, otherwise skipped
There are some function definitions that ‘check-declare’ does not
defstruct and some other macros). In such cases,
you can pass a non-
nil fileonly argument to
declare-function, meaning to only check that the file exists, not
that it actually defines the function. Note that to do this without
having to specify an argument list, you should set the arglist
nil means an empty argument list, as
opposed to an unspecified one).