標準化作業の初期の段階において ISO 規格委員会は、ライブラリ関数、マクロ、およびヘッダーファイルを ISO C の一部として含むことを選択しました。
この節では、さまざまな予約名のカテゴリとその予約名が必要な基本的な理由を示します。最後には、プログラムで予約名を使用しないようにするための規則を示します。
assert.h |
locale.h |
stddef.h |
ctype.h |
math.h |
stdio.h |
errno.h |
setjmp.h |
stdlib.h |
float.h |
signal.h |
string.h |
limits.h |
stdarg.h |
time.h |
ほとんどの実装では、さらに多くのヘッダーが用意されています。しかし、1990 ISO/IEC C に厳密に準拠するプログラムが使用できるのは、前述のヘッダーだけです。
これらヘッダーの一部の内容については、ほかの規格ではわずかに異なります。たとえば、POSIX (IEEE 1003.1) は、fdopen を stdio.h で宣言するように指定しています。これら 2 つの規格が共存するために、POSIX では、このような追加の名前が存在することを保証するためには任意のヘッダーをインクルードする前にマクロ _POSIX_SOURCE を #defined で定義しなければならないと規定しています。X/Open の『Portability Guide』によると、X/Open もこのマクロ方式を使用して拡張しています。X/Open のマクロは _XOPEN_SOURCE です。
ISO C は、標準ヘッダーがそれ自身だけで完結し、べき等 (何度指定しても同じ) であることを要求しています。どの標準ヘッダーも、その前後でほかのヘッダーを #included でインクルードする必要はありません。標準ヘッダーは何度 #included でインクルードしても、問題は発生しません。ISO C 規格では、安全なコンテキストにおいてのみ、標準ヘッダーを #included でインクルードすることを要求します。したがって、ヘッダーで使用される名前は変更されないことが保証されます。
ISO C 規格は、標準ライブラリについて、より多くの制限を実装に課しています。過去において、ほとんどのプログラマは UNIX システムでは独自の関数に read や write などの名前を使用しないように学びました。ISO C では、予約されている名前だけを実装内の参照で使用するように規定しています。
したがって ISO C 規格では、実装で使用する可能性があるすべての名前のサブセットが予約されています。この名前のクラスは下線で始まり、もう 1 つの下線または大文字の英字が続く識別子から構成されます。この名前のクラスは、次の正規表現に一致するすべての名前を含みます。
_[_A-Z][0-9_a-zA-Z]* |
厳密には、プログラムがこのような識別子を使用する場合、その動作は未定義です。したがって、_POSIX_SOURCE (または、_XOPEN_SOURCE) を使用するプログラムの動作は未定義です。
ただし、動作がどれぐらい未定義なのかは異なります。POSIX 準拠の実装で _POSIX_SOURCE を使用する場合、ユーザーのプログラムの未定義の動作が特定のヘッダー内に追加された特定の名前から構成されていることと、受け入れられる標準にユーザーのプログラムが準拠していることは予測できます。ISO C 規格におけるこの故意の抜け道により、実装は外見上互換性のない仕様に準拠できます。一方、POSIX 規格に準拠しない実装は、_POSIX_SOURCE などの名前に遭遇したとき、任意の方法で動作できます。
ISO C 規格では、下線で始まるほかのすべての名前が (局所的なスコープではなく) ヘッダーファイルにおける通常のファイルのスコープの識別子として、および構造体と共用体のタグとして使用するために予約されています。従来通り、_filbuf と _doprnt という名前の関数によりライブラリの隠れた部分を実装することはできます。
明示的に予約されたすべての名前に加えて、ISO C 規格は、次の特定のパターンに一致する名前を (実装と将来の規格用に) 予約しています。
表 6–3 拡張用の予約名
ファイル |
予約名のパターン |
---|---|
E[0-9A-Z].* |
|
ctype.h |
(to|is)[a-z].* |
locale.h |
LC_[A-Z].* |
math.h |
現在の関数名[fl] |
signal.h |
(SIG|SIG_)[A-Z].* |
stdlib.h |
str[a-z].* |
string.h |
(str|mem|wcs)[a-z].* |
前述のリストにおいて、大文字の英字で始まる名前はマクロで、関連するヘッダーがインクルードされるときだけ予約されます。残りの名前は関数を示し、大域的なオブジェクトや関数を指定する場合には使用できません。
ANSI/ISO C の予約名と衝突しないようにするためには、次の 4 つの簡単な規則に従う必要があります。
すべてのシステムヘッダーは、ユーザーのソースファイルの最初に #include でインクルードする。_POSIX_SOURCE または _XOPEN_SOURCE (あるいは、その両方) の #define 行がある場合は、そのあとでインクルードする。
下線で始まる名前は定義または宣言しない。
すべてのファイルスコープのタグと通常名の最初の数文字では、下線または大文字の英字を使用する。stdarg.h または varargs.h 内の va_ 接頭辞に注意する。
すべてのマクロ名の最初の数文字では、数字または小文字の英字を使用する。 errno.h を #included でインクルードする場合、E で始まるほとんどすべての名前は予約されています。