Next: Proper Use of Unsigned Types, Previous: Writing Good Comments, Up: Rules When Writing New C Code [Contents][Index]
Global variables whose names begin with ‘Q’ are constants whose
value is a symbol of a particular name. The name of the variable should
be derived from the name of the symbol using the same rules as for Lisp
primitives. These variables are initialized using a call to
defsymbol()
in the syms_of_*()
function. (This call
interns a symbol, sets the C variable to the resulting Lisp object, and
calls staticpro()
on the C variable to tell the
garbage-collection mechanism about this variable. What
staticpro()
does is add a pointer to the variable to a large
global array; when garbage-collection happens, all pointers listed in
the array are used as starting points for marking Lisp objects. This is
important because it’s quite possible that the only current reference to
the object is the C variable. In the case of symbols, the
staticpro()
doesn’t matter all that much because the symbol is
contained in obarray
, which is itself staticpro()
ed.
However, it’s possible that a naughty user could do something like
uninterning the symbol out of obarray
or even setting
obarray
to a different value [although this is likely to make
SXEmacs crash!].)
Please note: It is potentially deadly if you declare a
‘Q...’ variable in two different modules. The two calls to
defsymbol()
are no problem, but some linkers will complain about
multiply-defined symbols. The most insidious aspect of this is that
often the link will succeed anyway, but then the resulting executable
will sometimes crash in obscure ways during certain operations!
To avoid this problem, declare any symbols with common names (such as
text
) that are not obviously associated with this particular
module in the file general-slots.h. The “-slots” suffix
indicates that this is a file that is included multiple times in
general.c. Redefinition of preprocessor macros allows the
effects to be different in each context, so this is actually more
convenient and less error-prone than doing it in your module.
Global variables whose names begin with ‘V’ are variables that
contain Lisp objects. The convention here is that all global variables
of type Lisp_Object
begin with ‘V’, and all others don’t
(including integer and boolean variables that have Lisp
equivalents). Most of the time, these variables have equivalents in
Lisp, but some don’t. Those that do are declared this way by a call to
DEFVAR_LISP()
in the vars_of_*()
initializer for the
module. What this does is create a special symbol-value-forward
Lisp object that contains a pointer to the C variable, intern a symbol
whose name is as specified in the call to DEFVAR_LISP()
, and set
its value to the symbol-value-forward Lisp object; it also calls
staticpro()
on the C variable to tell the garbage-collection
mechanism about the variable. When eval
(or actually
symbol-value
) encounters this special object in the process of
retrieving a variable’s value, it follows the indirection to the C
variable and gets its value. setq
does similar things so that
the C variable gets changed.
Whether or not you DEFVAR_LISP()
a variable, you need to
initialize it in the vars_of_*()
function; otherwise it will end
up as all zeroes, which is the integer 0 (not nil
), and
this is probably not what you want. Also, if the variable is not
DEFVAR_LISP()
ed, you must call staticpro()
on the
C variable in the vars_of_*()
function. Otherwise, the
garbage-collection mechanism won’t know that the object in this variable
is in use, and will happily collect it and reuse its storage for another
Lisp object, and you will be the one who’s unhappy when you can’t figure
out how your variable got overwritten.
Next: Proper Use of Unsigned Types, Previous: Writing Good Comments, Up: Rules When Writing New C Code [Contents][Index]