不要在C程序里用的标识符


Contents

 

Introduction

  
If you want to write a portable C program, you have to be careful not to give your own definitions to any of the identifiers that are reserved by the C standard. The standard tells you which identifiers are reserved, but scatters the information through a rather thick (and expensive) book. 

The basic principles of reserved identifiers are in ISO subclause 7.1.3 (ANSI section 4.1.2.1), "Reserved Identifiers". There you are warned: 

if a program declares or defines an identifier with the same name as an identifier reserved in that context .., the behavior is undefined.
That means that if your program contains a statement like "extern int log;", the compiler is fully justified in turning your terminal into a large wart hog. Yes, the standard allows (3.16/1.6) such behavior, though market forces (and the laws of physics!) might not support it. More realistically, your program may or may not work right, and you may or may not get a diagnostic message. 

This page is intended mostly for my fellow C compiler users. Compiler writers have a related but different set of concerns.

C and C++

  
These are two different languages. But C++ has its historical roots in C, and many C programs (and C programmers!) get converted to C++. The namespace feature of C++ makes it very much easier for programmers to avoid identifier collisions -- except for the C++ keywords, which are a superset of the standard C keywords. 

The C++ standard is written so that a C++ compiler can compile almost any correct C program and produce equivalent code. To keep your program from being one of the unlucky exceptions, you might want to avoid using the C++ keywords as identifiers. I've listed them in their alphabetical places in the table. 

Reference: Bjarne Stroustrup, The C++ Programming Language, Third Edition, section B.2.2. 

Standards

  
This page reflects the first ISO/ANSI standard, finalized in 1989 ("C89"), with subsequent corrections and addenda. It does not yet reflect the new 1999 standard ("C99").Realistically, I doubt I'll be updating it for C99 any time soon. C99 programmers should consult the standard or another good reference for the reserved identifiers added by the new standard.

When this page refers to "the standard" or "standard C", it takes several documents into account, as listed below. None of them is available on the Web; they're sold by national standards bodies but at prices I can no longer afford. (For more information on how to acquire a copy of the standard, see Steve Summit's comp.lang.c FAQ.) 

  • the ANSI standard, formally American National Standard for Information Systems -- Programming Language -- C, ANSI X3.159-1989. The ANSI standard was subsequently adopted as an International Standard by ISO; the ISO standard then became current even in the US. 
  • the ISO standard (ISO/IEC 9899:1990), which has replaced the ANSI standard. The two are identical except for some minor wording changes and renumbering, so if you bought the ANSI standard (as I did) you don't need to buy the ISO standard. The ISO standard has been updated by two Technical Corrigenda and a Normative Addendum, referred to as TC1, TC2, and NA1. 
  • TC1, Technical Corrigendum 1, summarized at Normative Changes to ISO/IEC 9899:1990 in Technical Corrigendum 1 
  • TC2, Technical Corrigendum 2, summarized at ISO C Technical Corrigendum 2 
  • NA1, Normative Addendum 1, summarized at A brief description of Normative Addendum 1, by Clive D.W. Feather 

Clause and Section Numbers

  
The ISO and ANSI standards are substantively the same, but sections are numbered differently. Specifically, ANSI sections 2 through 4 correspond pretty closely (but not exactly) to ISO clauses 5 through 7. 

The table of reserved identifiers below shows the ISO subclause and ANSI section numbers. In text, I show both numbers with the ISO number first, like this: 7.1.3/4.1.2.1. 

[to document contents]

Safety Tips

  
There are several kinds of safety to be considered: 
  • Does your compiler implement the standard correctly? (This is mentioned only for completeness, since there's not much that most of us can do about it as a practical matter.) 
  • Does your program conform to the standard? If not, you can get unpredictable results. For instance, declaring a non-static function GetChanges( ) leads to undefined behavior. 
  • Is your program understandable by humans? For instance, you might define a big number in your program and call it HUGE_VAL. This is legal as long as that module doesn't also include math.h. But even though it's legal, it will probably confuse a human reading your program, if that person is familiar with math.h and unconsciously assumes that HUGE_VAL has its standard meaning. 
  • Is your program robust: can it tolerate apparently harmless changes without self-destructing? Or have you done some things that are legal but set traps for maintenance programmers (or yourself, six months hence)? For instance, it's legal to declare a global variable fwide, as long as no module in your executable includes wchar.h or wctype.h. But if later some other programmer, adding wide character support, includes either of those headers in another module, your executable is now broken and you have unpredictable results -- a crash at run time, if you're lucky, or subtly wrong results if you're not. 
On this page, I try to give you the information you need to choose your own level of safety. The table of reserved identifiers below includes a column showing the context in which each identifier is reserved. 

My own preference is for maximum safety: I try never to use any identifier for my own purposes if it's in the C standard. This appeals to my simple mind because it's simple! <grin> But those context notations can be useful even so: if a program is misbehaving and you suspect a standard identifier has been used in a non-standard way, you can make sure by checking the context in the table. 

You need to be aware of some surprising consequences of the standard: two identifiers can be spelled the same yet be distinct, or they can be spelled differently yet be the same, as I'll discuss next.

Surprise Number 1:
They Look Different, But They're the Same

  
Make sure that any names you define are unique in the first 31 characters for internal names, or 6 characters (upper and lower case not significant) for external names. The standard says (6.1.2/3.1.2) that conforming implementations can consider, for example, external names ABCDEFG and abcdefh to identify the same object or function. 

This means that all identifiers which are "the same" as names of library functions under the external-names equivalence are also reserved for use as externals. For example, there is undefined behavior if you name a non-static function or global variable

cleared( )      Stratford( )      CallOccasionally( )      reallocation

These conflict with

clearerr( )       the reservation of stranything      calloc( )      realloc( )

Though these names are permitted for your use as macros, automatic variables, etc., I suggest that you always remember the possibility of confusing your fellow programmers and stay away from them. 

Your compiler may not complain if you violate these constraints. For instance, your compiler may distinguish more than six characters for external names, or it may distinguish upper and lower case. But I think the rules are still worth following, because you never know when you'll have to port code to some other compiler that is not so discriminating, but still conforms to the letter of the standard.

Surprise Number 2:
They Look the Same, But They're Different

  
(If you're going for maximum safety, just skip to the next section.) 

Yes, it's possible to have two different identifiers that are spelled exactly the same. For instance, struct ceil doesn't conflict with the ceil( ) function, even if you've included the math.h header that declares it. And extern int grouping doesn't conflict with grouping, the member of struct lconv defined in locale.h. In fact, you can legally define a different structure of your own with a member called grouping. (It may be confusing to humans, but it's legal.) 

There's no conflict because the identifiers in those examples are in different name spaces. The standard lists (6.1.2.3/3.1.2.3) these separate name spaces: 

  • label names 
  • tags of struct, union, and enum (one combined name space for all the tags) 
  • members of struct and union (a separate name space for each struct or union
  • ordinary identifiers, which I interpret to comprise objects, functions, and typedef names 
An identifier in one name space can't conflict with an identically-named identifier in a different name space. (They also can't conflict if their scopes don't overlap, which is why you can name automatic variables in one function without worrying about the names of other functions or their automatic variables.) 

Macro names have their own name space, according to ISO 6.8.3/ANSI 3.8.3: "There is one name space for macro names." But of course you must not create a conflict between a macro and an ordinary name. 

[to document contents]

The Reserved Identifiers

Groups of Reserved Identifiers

  
Respect that first entry in the table below: never make up any identifier that starts with an underscore. 
Actually, you can legally use an identifier that starts with an underscore if the second character is a lower-case letter or a digit, and the identifier is used inside a function or a function prototype or as a structure member or label. Easier just not to use leading underscores!
There are various other table entries with "[any]". For instance, no matter which headers you use, you must never create a non-static function or global variable that starts with the letters is, mem, str, to, or wcs. Additional classes of identifiers are reserved if you include particular headers, as indicated in the table.

The Table

  
Here's an explanation of the columns of the table: 
  • identifier: the reserved identifier. (Remember that identifiers that look different may still be the same as far as the compiler knows.) Some entries are shown as pseudo-regular expressions: for example, LC_[A-Z][any] means any identifier that begins with capital LC, an underscore, and another capital letter. The sort order is underscore first, digits next, letters (mixed caps and lower case) last.

  • _ | A | B | C | D | E | F | G-H | I-J | L | M | N-O | P-Q | R | S | T | U | V | W-X
  • context: See the notes following the table. 
  • header: the header file or other mechanism that declares or defines the reserved identifier. "predef" marks a predefined identifier for use on preprocessor lines; "keyword" means one of the languages's few keywords. 
  • ISO and ANSI: the subclause/section of the standards that most clearly reserves or describes the identifier. 
 
identifier       context    header     ISO        ANSI
                                                           
_[any]         (see Groups)           7.1.3      4.1.2.1
_[_A-Z][any]       all                7.1.3      4.1.2.1
__DATE__           all     (predef)   6.8.8      3.8.8
__FILE__           all     (predef)   6.8.8      3.8.8
__LINE__           all     (predef)   6.8.8      3.8.8
__STDC__           all     (predef)   6.8.8      3.8.8
__STDC_VERSION__   all     (predef)   NA1
__TIME__           all     (predef)   6.8.8      3.8.8
_IOFBF             H       stdio.h    7.9.1      4.9.1
_IOLBF             H       stdio.h    7.9.1      4.9.1
_IONBF             H       stdio.h    7.9.1      4.9.1
 
identifier       context    header     ISO        ANSI

abort              ext     stdlib.h   7.10.4.1   4.10.4.1
abs                ext     stdlib.h   7.10.6.1   4.10.6.1
acos               ext     math.h     7.5.2.1    4.5.2.1
acosf, acosl       ext     math.h     7.13.4     4.13.4
and                H/C++   iso646.h   NA1
and_eq             H/C++   iso646.h   NA1
asctime            ext     time.h     7.12.3.1   4.12.3.1
asin               ext     math.h     7.5.2.2    4.5.2.2
asinf, asinl       ext     math.h     7.13.4     4.13.4
asm                C++ only
assert             H       assert.h   7.2        4.2
atan               ext     math.h     7.5.2.3    4.5.2.3
atan2              ext     math.h     7.5.2.4    4.5.2.4
atan2f, atan2l     ext     math.h     7.13.4     4.13.4
atanf, atanl       ext     math.h     7.13.4     4.13.4
atexit             ext     stdlib.h   7.10.4.2   4.10.4.2
atof               ext     stdlib.h   7.10.1.1   4.10.1.1
atoi               ext     stdlib.h   7.10.1.2   4.10.1.2
atol               ext     stdlib.h   7.10.1.3   4.10.1.3
auto               all     (keyword)  6.1.1      3.1.1
 
identifier       context    header     ISO        ANSI

bitand             H/C++   iso646.h   NA1
bitor              H/C++   iso646.h   NA1
bool               C++ only
break              all     (keyword)  6.1.1      3.1.1
bsearch            ext     stdlib.h   7.10.5.1   4.10.5.1
btowc              extW    wchar.h    NA1
BUFSIZ             H       stdio.h    7.9.1      4.9.1
 
identifier       context    header     ISO        ANSI

calloc             ext     stdlib.h   7.10.3.1   4.10.3.1
case               all     (keyword)  6.1.1      3.1.1
catch              C++ only
ceil               ext     math.h     7.5.6.1    4.5.6.1
ceilf, ceill       ext     math.h     7.13.4     4.13.4
char               all     (keyword)  6.1.1      3.1.1
CHAR_BIT           H       limits.h   5.2.4.2.1  2.2.4.2.1
CHAR_MAX           H       limits.h   5.2.4.2.1  2.2.4.2.1
CHAR_MIN           H       limits.h   5.2.4.2.1  2.2.4.2.1
class              C++ only
clearerr           ext     stdio.h    7.9.10.1   4.9.10.1
clock              ext     time.h     7.12.2.1   4.12.2.1
clock_t (type)     H       time.h     7.12.1     4.12.1
CLOCKS_PER_SEC     H       time.h     7.12.1     4.12.1
compl              H/C++   iso646.h   NA1
const              all     (keyword)  6.1.1      3.1.1
const_cast         C++ only
continue           all     (keyword)  6.1.1      3.1.1
cos                ext     math.h     7.5.2.5    4.5.2.5
cosf               ext     math.h     7.13.4     4.13.4
cosh               ext     math.h     7.5.3.1    4.5.3.1
coshf, coshl       ext     math.h     7.13.4     4.13.4
cosl               ext     math.h     7.13.4     4.13.4
ctime              ext     time.h     7.12.3.2   4.12.3.2
currency_symbol    Hmem    locale.h   7.4        4.4
 
identifier       context    header     ISO        ANSI

DBL_DIG            H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_EPSILON        H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MANT_DIG       H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MAX            H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MAX_10_EXP     H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MAX_EXP        H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MIN            H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MIN_10_EXP     H       float.h    5.2.4.2.2  2.2.4.2.2
DBL_MIN_EXP        H       float.h    5.2.4.2.2  2.2.4.2.2
decimal_point      Hmem    locale.h   7.4        4.4
default            all     (keyword)  6.1.1      3.1.1
defined            all     (predef)   6.8.8      3.8.8
delete             C++ only
difftime           ext     time.h     7.12.2.2   4.12.2.2
div                ext     stdlib.h   7.10.6.2   4.10.6.2
div_t (type)       H       stdlib.h   7.10       4.10
do                 all     (keyword)  6.1.1      3.1.1
double             all     (keyword)  6.1.1      3.1.1
dynamic_cast       C++ only
 
identifier       context    header     ISO        ANSI

E[0-9A-Z][any]     H       errno.h    7.13.1     4.13.1
EDOM               H       errno.h    7.1.4      4.1.3
EILSEQ             H       errno.h    NA1
else               all     (keyword)  6.1.1      3.1.1
enum               all     (keyword)  6.1.1      3.1.1
EOF                H       stdio.h    7.9.1      4.9.1
ERANGE             H       errno.h    7.1.4      4.1.3
errno              H       errno.h    7.1.4      4.1.3
exit               ext     stdlib.h   7.10.4.3   4.10.4.3
EXIT_FAILURE       H       stdlib.h   7.10       4.10
EXIT_SUCCESS       H       stdlib.h   7.10       4.10
exp                ext     math.h     7.5.4.1    4.5.4.1
expf, expl         ext     math.h     7.13.4     4.13.4
explicit           C++ only
export             C++ only
extern             all     (keyword)  6.1.1      3.1.1
 
identifier       context    header     ISO        ANSI

fabs               ext     math.h     7.5.6.2    4.5.6.2
fabsf, fabsl       ext     math.h     7.13.4     4.13.4
false              C++ only
fclose             ext     stdio.h    7.9.5.1    4.9.5.1
feof               ext     stdio.h    7.9.10.2   4.9.10.2
ferror             ext     stdio.h    7.9.10.3   4.9.10.3
fflush             ext     stdio.h    7.9.5.2    4.9.5.2
fgetc              ext     stdio.h    7.9.7.1    4.9.7.1
fgetpos            ext     stdio.h    7.9.9.1    4.9.9.1
fgets              ext     stdio.h    7.9.7.2    4.9.7.2
fgetwc             extW    wchar.h    NA1
fgetws             extW    wchar.h    NA1
FILE (type)        H       stdio.h    7.9.1      4.9.1
FILENAME_MAX       H       stdio.h    7.9.1      4.9.1
float              all     (keyword)  6.1.1      3.1.1
floor              ext     math.h     7.5.6.3    4.5.6.3
floorf, floorl     ext     math.h     7.13.4     4.13.4
FLT_DIG            H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_EPSILON        H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MANT_DIG       H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MAX            H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MAX_10_EXP     H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MAX_EXP        H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MIN            H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MIN_10_EXP     H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_MIN_EXP        H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_RADIX          H       float.h    5.2.4.2.2  2.2.4.2.2
FLT_ROUNDS         H       float.h    5.2.4.2.2  2.2.4.2.2
fmod               ext     math.h     7.5.6.4    4.5.6.4
fmodf, fmodl       ext     math.h     7.13.4     4.13.4
fopen              ext     stdio.h    7.9.5.3    4.9.5.3
FOPEN_MAX          H       stdio.h    7.9.1      4.9.1
for                all     (keyword)  6.1.1      3.1.1
fpos_t (type)      H       stdio.h    7.9.1      4.9.1
fprintf            ext     stdio.h    7.9.6.1    4.9.6.1
fputc              ext     stdio.h    7.9.7.3    4.9.7.3
fputs              ext     stdio.h    7.9.7.4    4.9.7.4
fputwc             extW    wchar.h    NA1
fputws             extW    wchar.h    NA1
frac_digits        Hmem    locale.h   7.4        4.4
fread              ext     stdio.h    7.9.8.1    4.9.8.1
free               ext     stdlib.h   7.10.3.2   4.10.3.2
freopen            ext     stdio.h    7.9.5.4    4.9.5.4
frexp              ext     math.h     7.5.4.2    4.5.4.2
frexpf, frexpl     ext     math.h     7.13.4     4.13.4
friend             C++ only
fscanf             ext     stdio.h    7.9.6.2    4.9.6.2
fseek              ext     stdio.h    7.9.9.2    4.9.9.2
fsetpos            ext     stdio.h    7.9.9.3    4.9.9.3
ftell              ext     stdio.h    7.9.9.4    4.9.9.4
fwide              extW    wchar.h    NA1
fwprintf           extW    wchar.h    NA1
fwrite             ext     stdio.h    7.9.8.2    4.9.8.2
fwscanf            extW    wchar.h    NA1
 
identifier       context    header     ISO        ANSI

getc               ext     stdio.h    7.9.7.5    4.9.7.5
getchar            ext     stdio.h    7.9.7.6    4.9.7.6
getenv             ext     stdlib.h   7.10.4.4   4.10.4.4
gets               ext     stdio.h    7.9.7.7    4.9.7.7
getwc              extW    wchar.h    NA1
getwchar           extW    wchar.h    NA1
gmtime             ext     time.h     7.12.3.3   4.12.3.3
goto               all     (keyword)  6.1.1      3.1.1
grouping           Hmem    locale.h   7.4        4.4
                                                           
HUGE_VAL           H       math.h     7.5        4.5
 
identifier       context    header     ISO        ANSI

if                 all     (keyword)  6.1.1      3.1.1
inline             C++ only
int                all     (keyword)  6.1.1      3.1.1
int_curr_symbol    Hmem    locale.h   7.4        4.4
int_frac_digits    Hmem    locale.h   7.4        4.4
INT_MAX            H       limits.h   5.2.4.2.1  2.2.4.2.1
INT_MIN            H       limits.h   5.2.4.2.1  2.2.4.2.1
is[a-z][any]       ext     ctype.h    7.13.2     4.13.2
isalnum            ext     ctype.h    7.3.1.1    4.3.1.1
isalpha            ext     ctype.h    7.3.1.2    4.3.1.2
iscntrl            ext     ctype.h    7.3.1.3    4.3.1.3
isdigit            ext     ctype.h    7.3.1.4    4.3.1.4
isgraph            ext     ctype.h    7.3.1.5    4.3.1.5
islower            ext     ctype.h    7.3.1.6    4.3.1.6
isprint            ext     ctype.h    7.3.1.7    4.3.1.7
ispunct            ext     ctype.h    7.3.1.8    4.3.1.8
isspace            ext     ctype.h    7.3.1.9    4.3.1.9
isupper            ext     ctype.h    7.3.1.10   4.3.1.10
iswalnum           extW    wctype.h   NA1
iswalpha           extW    wctype.h   NA1
iswcntrl           extW    wctype.h   NA1
iswctype           extW    wctype.h   NA1
iswdigit           extW    wctype.h   NA1
iswgraph           extW    wctype.h   NA1
iswlower           extW    wctype.h   NA1
iswprint           extW    wctype.h   NA1
iswpunct           extW    wctype.h   NA1
iswspace           extW    wctype.h   NA1
iswupper           extW    wctype.h   NA1
iswxdigit          extW    wctype.h   NA1
isxdigit           ext     ctype.h    7.3.1.11   4.3.1.11
                                                           
jmp_buf (type)     H       setjmp.h   7.6        4.6
 
identifier       context    header     ISO        ANSI

L_tmpnam           H       stdio.h    7.9.1      4.9.1
labs               ext     stdlib.h   7.10.6.3   4.10.6.3
LC_[A-Z][any]      H       locale.h   7.13.3     4.13.3
LC_ALL             H       locale.h   7.4        4.4
LC_COLLATE         H       locale.h   7.4        4.4
LC_CTYPE           H       locale.h   7.4        4.4
LC_MONETARY        H       locale.h   7.4        4.4
LC_NUMERIC         H       locale.h   7.4        4.4
LC_TIME            H       locale.h   7.4        4.4
lconv (struct)     Htag    locale.h   7.4        4.4
LDBL_DIG           H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_EPSILON       H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MANT_DIG      H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MAX           H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MAX_10_EXP    H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MAX_EXP       H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MIN           H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MIN_10_EXP    H       float.h    5.2.4.2.2  2.2.4.2.2
LDBL_MIN_EXP       H       float.h    5.2.4.2.2  2.2.4.2.2
ldexp              ext     math.h     7.5.4.3    4.5.4.3
ldexpf, ldexpl     ext     math.h     7.13.4     4.13.4
ldiv               ext     stdlib.h   7.10.6.4   4.10.6.4
ldiv_t (type)      H       stdlib.h   7.10       4.10
localeconv         ext     locale.h   7.4.2.1    4.4.2.1
localtime          ext     time.h     7.12.3.4   4.12.3.4
log                ext     math.h     7.5.4.4    4.5.4.4
log10              ext     math.h     7.5.4.5    4.5.4.5
log10f, log10l     ext     math.h     7.13.4     4.13.4
logf, logl         ext     math.h     7.13.4     4.13.4
long               all     (keyword)  6.1.1      3.1.1
LONG_MAX           H       limits.h   5.2.4.2.1  2.2.4.2.1
LONG_MIN           H       limits.h   5.2.4.2.1  2.2.4.2.1
longjmp            ext     setjmp.h   7.6.2.1    4.6.2.1
 
identifier       context    header     ISO        ANSI

malloc             ext     stdlib.h   7.10.3.3   4.10.3.3
MB_CUR_MAX         H       stdlib.h   7.10       4.10
MB_LEN_MAX         H       limits.h   5.2.4.2.1  2.2.4.2.1
mblen              ext     stdlib.h   7.10.7.1   4.10.7.1
mbrlen             extW    wchar.h    NA1
mbrtowc            extW    wchar.h    NA1
mbsinit            extW    wchar.h    NA1
mbsrtowcs          extW    wchar.h    NA1
mbstate_t (type)   H       wchar.h    NA1
mbstowcs           ext     stdlib.h   7.10.8.1   4.10.8.1
mbtowc             ext     stdlib.h   7.10.7.2   4.10.7.2
mem[a-z][any]      ext     string.h   7.13.8     4.13.8
memchr             ext     string.h   7.11.5.1   4.11.5.1
memcmp             ext     string.h   7.11.4.1   4.11.4.1
memcpy             ext     string.h   7.11.2.1   4.11.2.1
memmove            ext     string.h   7.11.2.2   4.11.2.2
memset             ext     string.h   7.11.6.1   4.11.6.1
mktime             ext     time.h     7.12.2.3   4.12.2.3
modf               ext     math.h     7.5.4.6    4.5.4.6
modff, modfl       ext     math.h     7.13.4     4.13.4
mon_decimal_point  Hmem    locale.h   7.4        4.4
mon_grouping       Hmem    locale.h   7.4        4.4
mon_thousands_sep  Hmem    locale.h   7.4        4.4
mutable            C++ only
 
identifier       context    header     ISO        ANSI

n_cs_precedes      Hmem    locale.h   7.4        4.4
n_sep_by_space     Hmem    locale.h   7.4        4.4
n_sign_posn        Hmem    locale.h   7.4        4.4
namespace          C++ only
NDEBUG             H       assert.h   7.2        4.2
negative_sign      Hmem    locale.h   7.4        4.4
new                C++ only
not                H/C++   iso646.h   NA1
not_eq             H/C++   iso646.h   NA1
NULL               H       many       many
                                                           
offsetof           H       stddef.h   7.1.6      4.1.5
operator           C++ only
or                 H/C++   iso646.h   NA1
or_eq              H/C++   iso646.h   NA1
 
identifier       context    header     ISO        ANSI

p_cs_precedes      Hmem    locale.h   7.4        4.4
p_sep_by_space     Hmem    locale.h   7.4        4.4
p_sign_posn        Hmem    locale.h   7.4        4.4
perror             ext     stdio.h    7.9.10.4   4.9.10.4
positive_sign      Hmem    locale.h   7.4        4.4
pow                ext     math.h     7.5.5.1    4.5.5.1
powf, powl         ext     math.h     7.13.4     4.13.4
printf             ext     stdio.h    7.9.6.3    4.9.6.3
private            C++ only
protected          C++ only
ptrdiff_t (type)   H       stddef.h   7.1.6      4.1.5
public             C++ only
putc               ext     stdio.h    7.9.7.8    4.9.7.8
putchar            ext     stdio.h    7.9.7.9    4.9.7.9
puts               ext     stdio.h    7.9.7.10   4.9.7.10
putwc              extW    wchar.h    NA1
putwchar           extW    wchar.h    NA1
                                                           
qsort              ext     stdlib.h   7.10.5.2   4.10.5.2
 
identifier       context    header     ISO        ANSI

raise              ext     signal.h   7.7.2.1    4.7.2.1
rand               ext     stdlib.h   7.10.2.1   4.10.2.1
RAND_MAX           H       stdlib.h   7.10       4.10
realloc            ext     stdlib.h   7.10.3.4   4.10.3.4
register           all     (keyword)  6.1.1      3.1.1
reinterpret_cast   C++ only
remove             ext     stdio.h    7.9.4.1    4.9.4.1
rename             ext     stdio.h    7.9.4.2    4.9.4.2
return             all     (keyword)  6.1.1      3.1.1
rewind             ext     stdio.h    7.9.9.5    4.9.9.5
 
identifier       context    header     ISO        ANSI

scanf              ext     stdio.h    7.9.6.4    4.9.6.4
SCHAR_MAX          H       limits.h   5.2.4.2.1  2.2.4.2.1
SCHAR_MIN          H       limits.h   5.2.4.2.1  2.2.4.2.1
SEEK_CUR           H       stdio.h    7.9.1      4.9.1
SEEK_END           H       stdio.h    7.9.1      4.9.1
SEEK_SET           H       stdio.h    7.9.1      4.9.1
setbuf             ext     stdio.h    7.9.5.5    4.9.5.5
setjmp             H       setjmp.h   7.6.1.1    4.6.1.1
setlocale          ext     locale.h   7.4.1.1    4.4.1.1
setvbuf            ext     stdio.h    7.9.5.6    4.9.5.6
short              all     (keyword)  6.1.1      3.1.1
SHRT_MAX           H       limits.h   5.2.4.2.1  2.2.4.2.1
SHRT_MIN           H       limits.h   5.2.4.2.1  2.2.4.2.1
SIG_[A-Z][any]     H       signal.h   7.7        4.7
sig_atomic_t(type) H       signal.h   7.7        4.7
SIG_DFL            H       signal.h   7.7        4.7
SIG_ERR            H       signal.h   7.7        4.7
SIG_IGN            H       signal.h   7.7        4.7
SIG[A-Z][any]      H       signal.h   7.7        4.7
SIGABRT            H       signal.h   7.7        4.7
SIGFPE             H       signal.h   7.7        4.7
SIGILL             H       signal.h   7.7        4.7
SIGINT             H       signal.h   7.7        4.7
signal             ext     signal.h   7.7.1.1    4.7.1.1
signed             all     (keyword)  6.1.1      3.1.1
SIGSEGV            H       signal.h   7.7        4.7
SIGTERM            H       signal.h   7.7        4.7
sin                ext     math.h     7.5.2.6    4.5.2.6
sinf               ext     math.h     7.13.4     4.13.4
sinh               ext     math.h     7.5.3.2    4.5.3.2
sinhf, sinhl       ext     math.h     7.13.4     4.13.4
sinl               ext     math.h     7.13.4     4.13.4
size_t (type)      ext     many       many
sizeof             all     (keyword)  6.1.1      3.1.1
sprintf            ext     stdio.h    7.9.6.5    4.9.6.5
sqrt               ext     math.h     7.5.5.2    4.5.5.2
sqrtf, sqrtl       ext     math.h     7.13.4     4.13.4
srand              ext     stdlib.h   7.10.2.1   4.10.2.1
sscanf             ext     stdio.h    7.9.6.6    4.9.6.6
static             all     (keyword)  6.1.1      3.1.1
static_cast        C++ only
stderr             H       stdio.h    7.9.1      4.9.1
stdin              H       stdio.h    7.9.1      4.9.1
stdout             H       stdio.h    7.9.1      4.9.1
str[a-z][any]      ext     stdlib.h   7.13.7     4.13.7
str[a-z][any]      ext     string.h   7.13.8     4.13.8
strcat             ext     string.h   7.11.3.1   4.11.3.1
strchr             ext     string.h   7.11.5.2   4.11.5.2
strcmp             ext     string.h   7.11.4.2   4.11.4.2
strcoll            ext     string.h   7.11.4.3   4.11.4.3
strcpy             ext     string.h   7.11.2.3   4.11.2.3
strcspn            ext     string.h   7.11.5.3   4.11.5.3
strerror           ext     string.h   7.11.6.2   4.11.6.2
strftime           ext     time.h     7.12.3.5   4.12.3.5
strlen             ext     string.h   7.11.6.3   4.11.6.3
strncat            ext     string.h   7.11.3.2   4.11.3.2
strncmp            ext     string.h   7.11.4.4   4.11.4.4
strncpy            ext     string.h   7.11.2.4   4.11.2.4
strpbrk            ext     string.h   7.11.5.4   4.11.5.4
strrchr            ext     string.h   7.11.5.5   4.11.5.5
strspn             ext     string.h   7.11.5.6   4.11.5.6
strstr             ext     string.h   7.11.5.7   4.11.5.7
strtod             ext     stdlib.h   7.10.1.4   4.10.1.4
strtok             ext     string.h   7.11.5.8   4.11.5.8
strtol             ext     stdlib.h   7.10.1.5   4.10.1.5
strtoul            ext     stdlib.h   7.10.1.6   4.10.1.6
struct             all     (keyword)  6.1.1      3.1.1
strxfrm            ext     string.h   7.11.4.5   4.11.4.5
switch             all     (keyword)  6.1.1      3.1.1
swprintf           extW    wchar.h    NA1
swscanf            extW    wchar.h    NA1
system             ext     stdlib.h   7.10.4.5   4.10.4.5
 
identifier       context    header     ISO        ANSI

tan                ext     math.h     7.5.2.7    4.5.2.7
tanf               ext     math.h     7.13.4     4.13.4
tanh               ext     math.h     7.5.3.3    4.5.3.3
tanhf, tanhl       ext     math.h     7.13.4     4.13.4
tanl               ext     math.h     7.13.4     4.13.4
template           C++ only
this               C++ only
thousands_sep      Hmem    locale.h   7.4        4.4
throw              C++ only
time               ext     time.h     7.12.2.4   4.12.2.4
time_t (type)      H       time.h     7.12.1     4.12.1
tm (struct)        Htag    time.h     7.12.1     4.12.1
tm (struct)        Htag    wchar.h    NA1
tm_hour            Hmem    time.h     7.12.1     4.12.1
tm_isdst           Hmem    time.h     7.12.1     4.12.1
tm_mday            Hmem    time.h     7.12.1     4.12.1
tm_min             Hmem    time.h     7.12.1     4.12.1
tm_mon             Hmem    time.h     7.12.1     4.12.1
tm_sec             Hmem    time.h     7.12.1     4.12.1
tm_wday            Hmem    time.h     7.12.1     4.12.1
tm_yday            Hmem    time.h     7.12.1     4.12.1
tm_year            Hmem    time.h     7.12.1     4.12.1
TMP_MAX            H       stdio.h    7.9.1      4.9.1
tmpfile            ext     stdio.h    7.9.4.3    4.9.4.3
tmpnam             ext     stdio.h    7.9.4.4    4.9.4.4
to[a-z][any]       ext     ctype.h    7.13.2     4.13.2
tolower            ext     ctype.h    7.3.2.1    4.3.2.1
toupper            ext     ctype.h    7.3.2.2    4.3.2.2
towctrans          extW    wctype.h   NA1
towlower           extW    wctype.h   NA1
towupper           extW    wctype.h   NA1
true               C++ only
try                C++ only
typedef            all     (keyword)  6.1.1      3.1.1
typeid             C++ only
typename           C++ only
 
identifier       context    header     ISO        ANSI

UCHAR_MAX          H       limits.h   5.2.4.2.1  2.2.4.2.1
UINT_MAX           H       limits.h   5.2.4.2.1  2.2.4.2.1
ULONG_MAX          H       limits.h   5.2.4.2.1  2.2.4.2.1
ungetc             ext     stdio.h    7.9.7.11   4.9.7.11
ungetwc            extW    wchar.h    NA1
union              all     (keyword)  6.1.1      3.1.1
unsigned           all     (keyword)  6.1.1      3.1.1
USHRT_MAX          H       limits.h   5.2.4.2.1  2.2.4.2.1
using              C++ only
 
identifier       context    header     ISO        ANSI

va_arg             H       stdarg.h   7.8.1      4.8.1
va_end             H       stdarg.h   7.8.1      4.8.1
va_list (type)     H       stdarg.h   7.8        4.8
va_start           H       stdarg.h   7.8.1      4.8.1
vfprintf           ext     stdio.h    7.9.6.7    4.9.6.7
vfwprintf          extW    wchar.h    NA1
virtual            C++ only
void               all     (keyword)  6.1.1      3.1.1
volatile           all     (keyword)  6.1.1      3.1.1
vprintf            ext     stdio.h    7.9.6.8    4.9.6.8
vsprintf           ext     stdio.h    7.9.6.9    4.9.6.9
vswprintf          extW    wchar.h    NA1
vwprintf           extW    wchar.h    NA1
 
identifier       context    header     ISO        ANSI

WCHAR_MAX          H       wchar.h    NA1
WCHAR_MIN          H       wchar.h    NA1
wchar_t (type)     H/C++   stddef.h   7.1.6      4.1.5
wchar_t (type)     H/C++   stdlib.h   7.10       4.10
wchar_t (type)     H/C++   wchar.h    NA1
wcrtomb            extW    wchar.h    NA1
wcs[a-z][any]      ext     string.h   7.13.8     4.13.8
wcs[a-z][any]      extW    wchar.h    NA1
wcscat             extW    wchar.h    NA1
wcschr             extW    wchar.h    NA1
wcscmp             extW    wchar.h    NA1
wcscoll            extW    wchar.h    NA1
wcscpy             extW    wchar.h    NA1
wcscspn            extW    wchar.h    NA1
wcsftime           extW    wchar.h    NA1
wcslen             extW    wchar.h    NA1
wcsncat            extW    wchar.h    NA1
wcsncmp            extW    wchar.h    NA1
wcsncpy            extW    wchar.h    NA1
wcspbrk            extW    wchar.h    NA1
wcsrchr            extW    wchar.h    NA1
wcsrtombs          extW    wchar.h    NA1
wcsspn             extW    wchar.h    NA1
wcsstr             extW    wchar.h    NA1
wcstod             extW    wchar.h    NA1
wcstok             extW    wchar.h    NA1
wcstol             extW    wchar.h    NA1
wcstombs           ext     stdlib.h   7.10.8.2   4.10.8.2
wcstoul            extW    wchar.h    NA1
wcsxfrm            extW    wchar.h    NA1
wctob              extW    wchar.h    NA1
wctomb             ext     stdlib.h   7.10.7.3   4.10.7.3
wctrans            extW    wctype.h   NA1
wctrans_t (type)   H       wctype.h   NA1
wctype             extW    wctype.h   NA1
wctype_t (type)    H       wctype.h   NA1
WEOF               H       wchar.h    NA1
WEOF               H       wctype.h   NA1
while              all     (keyword)  6.1.1      3.1.1
wint_t (type)      H       wchar.h    NA1
wint_t (type)      H       wctype.h   NA1
wmemchr            extW    wchar.h    NA1
wmemcmp            extW    wchar.h    NA1
wmemcpy            extW    wchar.h    NA1
wmemmove           extW    wchar.h    NA1
wmemset            extW    wchar.h    NA1
wprintf            extW    wchar.h    NA1
wscanf             extW    wchar.h    NA1
                                                           
xor                H/C++   iso646.h   NA1
xor_eq             H/C++   iso646.h   NA1

Context

  
The standard lists (7.1.3/4.1.2.1) the categories of reserved identifiers, where "reserved" means, essentially, prohibited for use by the individual C programmer. Recall that "if a program declares or defines an identifier with the same name as an identifier reserved in that context .., the behavior is undefined" (emphasis added). The "context" combines the concepts of scope (6.1.2.1/3.1.2.1), linkage (6.1.2.1/3.1.2.2), and name space (6.1.2.3/3.1.2.3). 

I've marked those contexts in the above table. The details follow, but remember that you don't have to be concerned with them: you'll be safe if you simply never use any of the above identifiers (or anything that starts with the same six characters in capitals or lower case) for your own purposes. 

  • all: always reserved. Most of these are keywords or predefined identifiers. 
  • C++ only: C++ keywords that have no meaning to standard C. Even so, you may want to avoid them, if there's any chance that your C program will ever be compiled by a C++ compiler. 
  • ext: always reserved for use with external linkage. This means that, even if you don't include the indicated header file, you still must never create global variables or non-static functions with these names. Strictly speaking, you can create local variables, static functions, typedefs, or macros with those names (depending on which headers you include, and other circumstances, you may need to #undef them first), but it's a bad idea because even if the compiler gets it right you'll confuse any humans who look at your program. 
  • extW: always reserved for use with external linkage, if and only if any module in your executable program includes wchar.h or wctype.h. Be careful: if module a.c includes either of those headers, module b.c must not declare any global variables or non-static functions with those names, even if module b.c does not include either of those headers. (Function names beginning with isw or tow are always reserved in external contexts under the original rule at 7.13.2/4.13.2.) 
  • H, Hmem, Htag: These contexts apply only in a module that includes the relevant header file. But for maximum safety I suggest that you stay away from them anyway. At least none of them are subject to the six-character rule
    • H: macro names and typedef names. These are in separate name spaces, but can still conflict with each other at the preprocessor level. I note types as such, but use no special notation for the much more numerous macros. (errno and va_end might be macros or externals, but your program must not #undef them or define external identifiers with those names.) 
    • Hmem: struct/union members: a separate name space for each struct or union. The compiler can't confuse them with your own names, but humans could. 
    • Htag: struct/union/enum tags. These share a common name space separate from the space for objects and functions. 
  • H/C++: same as plain H above, but used by C++ as keywords regardless what headers you include. My advice: if there's any chance you'll ever compile your C program with a C++ compiler, use these identifiers only in the standard C way. For example, a C compiler will let you redefine xor if you don't include iso646.h, but xor is a keyword to the C++ compiler. If you use these identifiers only with their standard C meanings, a C++ compiler should have no trouble with them.
[to document contents]

Acknowledgements

  
Mark Brader (msb@sq.com) was kind enough to send me a copy of his May 1992 Usenet article on the conversion between ANSI section and ISO (sub)clause numbers. I am also indebted to him for pointing out that user-selected external names must not match reserved external names even in the first six characters, and for many other helpful hints. 

Clive Feather's writeup on the Normative Addendum was invaluable; see Standards, above, for the URL. 

My thanks to Steve Summit and Bruce Evans for suggesting improvements in the Usenet article through a couple of revision cycles in 1992. My thanks also to Jutta Degener for pointing out in 1997 the need to take account of name spaces, so that e.g. extern int grouping; is in fact quite legal. 

Among our wonderful Net resources are the Swedish sitelysator.liu.se, which preserved this article at <http://gopher.lysator.liu.se:70/0/information/C/c-predefined>, and the Alta Vista search engine at http://www.altavista.digital.com/ for finding it. I had mislaid my own copy, and thus was happy to recover it in December 1996. (If you haven't searched Alta Vista for your own name, you might find the results enlightening.) 

Thanks are also due to David Yuan, http://www.cs.latrobe.edu.au/~yuand/, who thought it worth while offering to his students, and thus galvanized me to make my own HTMLized version available. 

Finally, if imitation is the sincerest form of flattery, I hope Bradd Szonye feels flattered. I liked the look of his Web pages enough to adapt some of his ideas for these pages. 

[to document contents]

What's New

  
  • 2000-12-02: run a long-overdue spell check and fix two typos 
  • 2000-09-30: add disclaimer about updating for the C99 standard 
  • 2000-07-18: remove link to historical copy at lysator, since the file is no longer there 
  • 2000-05-20 through -06-05: update for new domain name and improve navigation; no other significant changes 
  • (intervening changes suppressed) 
  • 1992-01-22 (first posted to Usenet newsgroups comp.std.c and comp.lang.c
 original page: http://oakroadsystems.com/tech/c-predef.htm