C Reserved Identifiers
revised 15 Sep 2003
Copyright © 1992–2004 Stan Brown, Oak Road Systems
You are here: OakRoadSystems Articles Technical C Reserved Identifiers |
revised 15 Sep 2003
Copyright © 1992–2004 Stan Brown, Oak Road Systems
Summary: The C standard reserves quite a few identifiers, meaning that you must not create variables, functions, or macros with those names. If you don't obey the restriction, you can have nasty subtle bugs in your program. This page lists the reserved identifiers and discusses the pitfalls.
You're welcome to print copies of this page for your own use, and to link from your own Web pages to this page. But please don't make any electronic copies and publish them on your Web page or elsewhere.
And for the litigious among us: The information here is offered without warranty of any kind. Sigh. Nevertheless, I intend to correct any errors that are drawn to my attention. Please let me know how you heard about this page when you send corrections and comments to me.
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.
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. On the other hand, if you're writing C++, please see my separate list of Identifiers to avoid in C++ programs.
Reference: Bjarne Stroustrup, The C++ Programming Language, Third Edition, section B.2.2, "C Code That Is Not C++".
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:
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
None of the official documents 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 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.
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 --#8212; 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.
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( ) CallOccasionally( ) reallocation
and Stratford( )
These conflict with
clearerr( ) calloc( ) realloc( )
and the reservation of str
anything
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.
(If you're going for maximum safety, ignore this section and 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:
struct
, union
, and enum
(one combined name space for all the tags)
struct
and union
(a separate name space
for each struct
or union
)
typedef
names
An identifier in one name space won't conflict with an identically-named identifier in a different name space. (They also won'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.
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
(7.13/4.13) a non-static
function or global variable that
starts with the letters is
, mem
,
str
, to
, or wcs
followed by a
lower-case letter. Additional classes of
identifiers are reserved if you include particular headers, as
indicated in the table.
Quick links to identifiers by initial letter:
_ |
A |
B |
C |
D |
E |
F |
G-H |
I-J |
L |
M |
N-O |
P-Q |
R |
S |
T |
U |
V |
W-X
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.
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; "future" means identifiers reserved for future use no matter what headers you include.
ISO and ANSI: the subclause/section of the C89 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 (future) 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 (future) 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 atanf, atanl ext (future) 7.13.4 4.13.4 atan2 ext math.h 7.5.2.4 4.5.2.4 atan2f, atan2l ext (future) 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 (future) 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 (future) 7.13.4 4.13.4 cosh ext math.h 7.5.3.1 4.5.3.1 coshf, coshl ext (future) 7.13.4 4.13.4 cosl ext (future) 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 (future) 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 (future) 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 (future) 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 (future) 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 (future) 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 (future) 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 (future) 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 logf, logl ext (future) 7.13.4 4.13.4 log10 ext math.h 7.5.4.5 4.5.4.5 log10f, log10l ext (future) 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 (future) 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 (future) 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 (future) 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 (future) 7.13.4 4.13.4 sinh ext math.h 7.5.3.2 4.5.3.2 sinhf, sinhl ext (future) 7.13.4 4.13.4 sinl ext (future) 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 (future) 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 (future) 7.13.7 4.13.7 str[a-z][any] ext (future) 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 (future) 7.13.4 4.13.4 tanh ext math.h 7.5.3.3 4.5.3.3 tanhf, tanhl ext (future) 7.13.4 4.13.4 tanl ext (future) 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 (future) 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 (future) 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
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
(7.1.3/4.1.2.1). 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, typedef
s, 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.
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 site
lysator.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.)
(intervening changes suppressed)
comp.std.c
and comp.lang.c
this page: http://oakroadsystems.com/tech/c-predef.htm
Was this page useful? Visit my other Technical Articles.