elisp: Declaring Functions

 
 12.15 Telling the Compiler that a Function is Defined
 =====================================================
 
 Byte-compiling a file often produces warnings about functions that the
 compiler doesn’t know about (SeeCompiler 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 ‘fortran.el’ used to warn:
 
      In end of data:
      fortran.el:2152:1:Warning: the function ‘gud-find-c-expr’ is not
          known to be defined.
 
    In fact, ‘gud-find-c-expr’ is only used in the function that Fortran
 mode uses for the local value of ‘gud-find-expr-function’, which is a
 callback from GUD; if it is called, the GUD functions will be loaded.
 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 ‘declare-function’.
 
    All you need to do is add a ‘declare-function’ statement before the
 first use of the function in question:
 
      (declare-function gud-find-c-expr "gud.el" nil)
 
    This says that ‘gud-find-c-expr’ is defined in ‘gud.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
 ‘gud-find-c-expr’.  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.
 
  -- Macro: declare-function function file &optional arglist fileonly
      Tell the byte compiler to assume that FUNCTION is defined, with
      arguments ARGLIST, and that the definition should come from the
      file FILE.  FILEONLY non-‘nil’ means only check that FILE exists,
      not that it actually defines FUNCTION.
 
    To verify that these functions really are declared where
 ‘declare-function’ says they are, use ‘check-declare-file’ to check all
 ‘declare-function’ calls in one source file, or use
 ‘check-declare-directory’ check all the files in and under a certain
 directory.
 
    These commands find the file that ought to contain a function’s
 definition using ‘locate-library’; if that finds no file, they expand
 the definition file name relative to the directory of the file that
 contains the ‘declare-function’ call.
 
    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
 without error.
 
    There are some function definitions that ‘check-declare’ does not
 understand (e.g., ‘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 argument to ‘t’ (because ‘nil’
 means an empty argument list, as opposed to an unspecified one).