"out of memory" and refused to print. The fault appeared randomly, and it was very hard to
track down. Finally, it was traced to an unintended interpositioning bug.
The programmer had implemented lpr with a routine, global by default, called mktemp(),
which expected three arguments. Unknown to the programmer, that duplicated a name
already present in the (pre-ANSI) C library, which did a similar job but only took one
argument.
Unfortunately, lpr also invoked the library routine getwd(), which expects to use the
library version of mktemp. Instead, it was bound to lpr 's special version! Thus, when
getwd() called mktemp, it put one argument on the stack, but the lpr version of
mktemp retrieved three. Depending on the random values it found, lpr failed with the "out
of memory" error.
Moral: Don't make any symbols in your program global, unless they are meant to be part of
your interface!
lpr was fixed by declaring its mktemp as static, making it invisible outside its own file (we
could equally have given it a different name). Mktemp has now been replaced by the library
routine tmpnam in ANSI C. However, the opportunity for the interpositioning problem
still exists.
If an identifier is shown in Table 5-2, never declare it in your own program. Some of these are always
reserved, and others are only reserved if you include a specific header file. Some of these are reserved
only in global scope, and others are reserved for both global and file scope. Also note that all
keywords are reserved, but are left out of the table below for simplicity. The easiest way to stay out of
trouble is to regard all these identifiers as belonging to the system at all times. Don't use them for your
identifiers.
Some entries look like is[a-z]anything.
This means any identifier that begins with the string "is" followed by any other lowercase letter (but
not, for example, a digit) followed by any characters.
Other entries look like acos,-f,-l.
This indicates that the three identifiers acos, acosf, and acosl are reserved. All routines in the
math header file have a basic version that takes a double-precision argument. There can also be two
extra versions: the basename with a l suffix is a version of the routine with quad precision arguments
(type "long double"), and the f suffix is a version with single precision ("float").
Table 5-2. Names to Avoid Using as Identifiers (Reserved for the System in ANSI C)
Don't Use These Names for Your Identifiers
_anything