feature_test_macros - 機能検査マクロ
#include <features.h>
機能検査マクロ (feature test macro)
により、プログラマは
プログラムがコンパイルされる際にシステムのヘッダファイルにより
公開される定義を制御することができる。
注意:
機能検査マクロを機能させるには、機能検査マクロの定義を
「どのヘッダファイルのインクルードよりも前で」行わなければならない。
これを実現するには、
コンパイルコマンドで指定する方法
(
cc -DMACRO=value)
と、ソースコード内で必要なマクロの定義を
どのヘッダのインクルードよりも前で行う方法がある。
機能検査マクロを使うと、非標準の定義が公開されないようにでき、
移植性のあるアプリケーションを作成するのに役立つ。
他のマクロを使うと、デフォルトでは公開されない非標準の定義を
公開することができる。
以下で説明する機能検査マクロのそれぞれの正確な影響を確認するには、
ヘッダファイル
<features.h>
を調べればよい。
マニュアルページでの機能検査マクロの要件の規定¶
関数が機能検査マクロの定義を必要とする場合、
マニュアルページの書式
(SYNOPSIS) の節に
以下の形式の注釈を入れる
(以下の例は
acct(2)
のマニュアルページからの引用である)。
#include <unistd.h>
int acct(const char *filename);
glibc 向けの機能検査マクロの要件
( feature_test_macros(7)
参照):
acct(): _BSD_SOURCE || (_XOPEN_SOURCE &&
_XOPEN_SOURCE < 500)
|| は、
acct(2) の定義を
<unistd.h>
から得るには、以下のマクロの定義のいずれかを、どのヘッダファイルの
インクルードよりも前で行わなければならないことを意味する。
#define _BSD_SOURCE
#define _XOPEN_SOURCE /* or any value < 500 */
別の方法としては、等価な定義をコンパイル用のコマンドで
指定することもできる。
cc -D_BSD_SOURCE
cc -D_XOPEN_SOURCE # Or any value < 500
後で述べるが、
「いくつかの機能検査マクロはデフォルトで定義される」
点に注意すること。
このため、「書式」に記載された機能検査マクロを常に
明示的に指定する必要があるわけではない。
あまり多くないが、マニュアルページによっては、
機能検査マクロの要件を以下のように簡単な表現で記載する場合がある。
(以下の例は
readahead(2)
のマニュアルページからの引用である)。
#define _GNU_SOURCE
#include <fcntl.h>
ssize_t readahead(int fd, off64_t *offset, size_t count);
関数定義の公開に使える機能検査マクロが一つだけで、
デフォルトではそのマクロが定義されない場合に、
この形式の表現を利用する。
glibc
が解釈する機能検査マクロ¶
以下では、Linux glibc 2.
x (
x >
0) において、
機能検査マクロがどのように扱われるかを説明する。
Linux/glibc
は以下の機能検査マクロを解釈する:
- __STRICT_ANSI__
- ISO 標準の C。 gcc(1)
を -std=c99 や -ansi
などのフラグを付けて起動した場合、
このマクロは暗黙のうちに定義される。
- _POSIX_C_SOURCE
- このマクロを定義すると、ヘッダファイルで以下の定義が公開される。
- •
- 値が 1
の場合、POSIX.1-1990 と ISO C (1990)
に準拠する定義が公開される。
- •
- 値が 2
以上の場合、 POSIX.2-1992
関連の定義も追加で公開される。
- •
- 値が 199309
以上の場合、 POSIX.1b
(リアルタイム拡張)
関連の定義が追加で公開される。
- •
- 値が 199506
以上の場合、 POSIX.1c
(スレッド)
関連の定義が追加で公開される。
- •
- (glibc 2.3.3 以降) 値が 200112L
以上の場合、 (XSI
拡張を除く) POSIX.1-2001
基本仕様に対応する定義が公開される。
- •
- (glibc 2.10 以降) 値が 200809L
以上の場合、 (XSI
拡張を除く) POSIX.1-2008
基本仕様に対応する定義が公開される。
- _POSIX_SOURCE
- このマクロは廃止予定である。
このマクロが定義されると、値に関わらず、
_POSIX_C_SOURCE を値 1
で定義するのと等価となる。
- _XOPEN_SOURCE
- このマクロを定義すると、ヘッダファイルで以下の定義が公開される。
- •
- どんな値でも、ヘッダファイルで
POSIX.1, POSIX.2, XPG4
に準拠する定義が公開される。
- •
- 値が 500
以上の場合、 SUSv2 (UNIX 98)
関連の定義が追加で公開される。
- •
- (glibc 2.2 以降) 値が 600
以上の場合、 SUSv3 (UNIX 03;
POSIX.1-2001 基本仕様 + XSI
拡張と同じ)
関連の定義と C99
での定義が追加で公開される。
- •
- (glibc 2.10 以降) 値が 700
以上の場合、 SUSv4 (POSIX.1-2008
基本仕様 + XSI
拡張と同じ)
関連の定義が追加で公開される。
- _XOPEN_SOURCE_EXTENDED
- このマクロが定義され、さらに
_XOPEN_SOURCE
が定義されていると、XPG4v2
(SUSv1) UNIX 拡張 (UNIX 95)
に対応する定義が公開される。
_XOPEN_SOURCE が 500
以上の値で定義された場合、このマクロは暗黙のうちに定義される。
- _ISOC95_SOURCE
- ISO C (1990) Amendment 1 の定義 (C95
としても知られる)
が公開される。 C95
における主要な変更点は国際化文字集合のサポートであった。
C95
の変更点は、これに続く
C99 標準にも含まれた
(言い換えると、
_ISOC99_SOURCE
を定義すると暗黙のうちに
_ISOC95_SOURCE
を定義されることを意味する)。
- _ISOC99_SOURCE
- ISO C (1990) の C99
拡張を公開する。
このマクロは glibc 2.1.3
以降で認識される。
初期のバージョン 2.1.x
の glibc
では、これと等価な
_ISOC9X_SOURCE
という名前のマクロが使われていた
(なぜなら、C99
標準はまだ確定していなかったからである)。
_ISOC9X_SOURCE
マクロの使用は廃止されているが、
glibc
は過去との互換性のため今でもこのマクロを認識する。
- _ISOC11_SOURCE
- ISO C11
標準に準拠した宣言を公開する。
このマクロは glibc 2.16
以降で認識される。
- _LARGEFILE64_SOURCE
- LFS (Large File Summit) により
"暫定拡張 (transitional extension)"
Single UNIX Specification
として規定された代替
API (alternative API)
に関する定義を公開する
(http://opengroup.org/platform/lfs.html 参照)。
代替 API
は新規オブジェクト
(関数と型)
の集合で構成され、
その名前は "64"
で終わる (例えば、
off_t に対応するのは
off64_t、 lseek()
に対応するのは lseek64()
である)。
新しいプログラムではこのインタフェースを利用しないこと。
代わりに _FILE_OFFSET_BITS=64
を利用すること。
- _FILE_OFFSET_BITS
- このマクロを値 64
で定義すると、ファイル
I/O
とファイルシステム操作に
関連する 32
ビット版の関数とデータタイプは自動的に
64 ビット版に
変換される。
これは、32
ビットシステムで大きなファイル
(> 2 ギガバイト) の I/O
を実行する際に役立つ
(このマクロを定義すると、コンパイルし直すだけで大きなファイルを
扱えるプログラムを書くことができる)。
64
ビットシステムは、もともと
2
ギガバイトより大きなファイルを
扱えるので、64
ビットシステムではこのマクロは効果を持たない。
- _BSD_SOURCE
- このマクロを定義すると
(値に関わらず)
ヘッダファイルで BSD
由来の定義が公開される。
また、このマクロを定義すると、相容れない標準が存在する状況において
BSD
由来の定義を優先するようになる。
ただし、 _SVID_SOURCE,
_POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE,
_XOPEN_SOURCE_EXTENDED, _GNU_SOURCE
が一つでも定義された場合には、BSD
由来の定義は優先されなくなる。
- _SVID_SOURCE
- このマクロを定義すると
(値に関わらず)
ヘッダファイルで System V
由来の定義が公開される
(SVID == System V Interface Definition; standards(7)
参照)。
- _ATFILE_SOURCE (glibc 2.4 以降)
- このマクロを定義すると
(値に関わらず)
ヘッダファイルで
名前の末尾が "at"
の各種の関数の定義が公開される。
openat(2) 参照。 glibc 2.10
以降では、 _POSIX_C_SOURCE が
200809L
以上の値で定義された場合には、
このマクロも暗黙のうちに定義される。
- _GNU_SOURCE
- このマクロを定義すると
(値に関わらず)
以下のマクロを定義するのと
等価になる: _BSD_SOURCE,
_SVID_SOURCE, _ATFILE_SOURCE, _LARGEFILE64_SOURCE,
_ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED,
_POSIX_SOURCE, 値 200809L の _POSIX_C_SOURCE
(バージョン 2.10
より前の glibc では値は
200112L、 バージョン 2.5
より前の glibc では値は
199506L、 バージョン 2.1
より前の glibc では値は
199309L), 値 700 の _XOPEN_SOURCE
(バージョン 2.10
より前の glibc では値は
600、 バージョン 2.2
より前の glibc では値は
500)。 さらに、各種の GNU
固有の拡張も公開される。
指定された標準に矛盾があった場合は、
BSD
由来の定義が優先されなくなる。
- _REENTRANT
- このマクロを定義すると、いくつかのリエントラント
(再入可能) な関数
定義が公開される。マルチスレッド・プログラムでは、この代わりに
cc -pthread
を使用すること。
- _THREAD_SAFE
- _REENTRANT の同義語。
他のいくつかの実装との互換性を提供するためのもの。
- _FORTIFY_SOURCE (glibc 2.3.4 以降)
- このマクロを定義すると、文字列やメモリの操作を行う様々な関数を
使用する際にバッファオーバーフローを検出するための軽めのチェックが
実行されるようになる。すべてのバッファオーバーフローが検出される
わけではなく、あくまでよくある例についてだけである。
現在の実装では、以下の関数にチェックが追加されている:
memcpy(3), mempcpy(3), memmove(3), memset(3),
stpcpy(3), strcpy(3), strncpy(3), strcat(3),
strncat(3), sprintf(3), snprintf(3),
vsprintf(3), vsnprintf(3), gets(3).
_FORTIFY_SOURCE が 1
に設定された場合、コンパイラの最適化レベルが
1 ( gcc -O1)
かそれ以上であれば、規格に準拠するプログラムの振る舞いを
変化させないようなチェックが実行される。
_FORTIFY_SOURCE が 2
に設定された場合、さらなるチェックが追加されるが、
規格に準拠するプログラムのいくつかが失敗する可能性がある。
いくつかのチェックはコンパイル時に実行でき、コンパイラの警告として
表示される。他のチェックは実行時に行われ、チェックに失敗した場合
には実行時エラーとなる。
このマクロを使用するにはコンパイラの対応が必要であり、
バージョン 4.0 以降の
gcc(1)
で利用できる。
デフォルトの定義、暗黙の定義、組み合わせ定義¶
機能検査マクロが一つも明示的に定義されなかった場合、
デフォルトで機能検査マクロ
_BSD_SOURCE,
_SVID_SOURCE,
_POSIX_SOURCE,
_POSIX_C_SOURCE=200809L
が定義される
(バージョン 2.10
より前の glibc では値は
200112L、 バージョン 2.4
より前の glibc では値は
199506L、 バージョン 2.1
より前の glibc では値は
199309L)。
__STRICT_ANSI__,
_ISOC99_SOURCE,
_POSIX_SOURCE,
_POSIX_C_SOURCE,
_XOPEN_SOURCE,
_XOPEN_SOURCE_EXTENDED,
_BSD_SOURCE,
_SVID_SOURCE
のいずれかが明示的に定義された場合、
_BSD_SOURCE と
_SVID_SOURCE
はデフォルトでは定義されない。
_POSIX_SOURCE と
_POSIX_C_SOURCE
が明示的に定義されない場合で、
__STRICT_ANSI__
が定義されない、もしくは
_XOPEN_SOURCE が 500
以上の値で定義されたときには、
- *
- _POSIX_SOURCE が値 1
で定義され、かつ
- *
- _POSIX_C_SOURCE
は以下の値のいずれか一つで定義される。
- •
- 2 (_XOPEN_SOURCE が 500
未満の値で定義された場合)
- •
- 199506L (_XOPEN_SOURCE が 500 以上
600
未満の値で定義された場合)
- •
- (glibc 2.4 以降) 200112L (XOPEN_SOURCE
が 600 以上 700
未満の値で定義された場合)
- •
- (glibc 2.10 以降) 200809L (XOPEN_SOURCE
が 700
以上の値で定義された場合)
- •
- 古いバージョンの
glibc では _POSIX_C_SOURCE
の値として 200112L や 200809L
は存在せず、 _POSIX_C_SOURCE
の値がどうなるかは
glibc
のバージョンにより異なる。
- •
- _XOPEN_SOURCE
が未定義の場合、
_POSIX_C_SOURCE の値は glibc
のバージョンにより異なる。
バージョン 2.4
より前の glibc では 199506L、
バージョン 2.4 以降 2.9
未満では 200112L、 glibc 2.10
以降では 200809L
となる。
また、複数のマクロを定義することもできる。
この場合、定義したマクロはすべて有効になる。
POSIX.1 では
_POSIX_C_SOURCE,
_POSIX_SOURCE,
_XOPEN_SOURCE
が規定されている。
_XOPEN_SOURCE_EXTENDED は XPG4v2 (別名 SUSv1)
で規定されていた。
_FILE_OFFSET_BITS
はどの標準でも規定されていないが、
他のいくつかの実装で採用されている。
_BSD_SOURCE,
_SVID_SOURCE,
_ATFILE_SOURCE,
_GNU_SOURCE,
_FORTIFY_SOURCE,
_REENTRANT,
_THREAD_SAFE は Linux (glibc)
固有である。
<features.h> は Linux/glibc
固有のヘッダファイルである。
他のシステムにも同様の目的のファイルがあるが、普通は違う名前である。
このヘッダファイルは、他のヘッダファイルにより必要に応じて
自動的にインクルードされる。機能検査マクロを利用するために
明示的にインクルードする必要はない。
上記の機能検査マクロのうちどれが定義されたかにしたがって、
<features.h> は、他の glibc
ヘッダファイルでチェックされる各種の他のマクロを、
内部で定義する。これらのマクロの名前はアンダースコア
2つで始まる (例えば
__USE_MISC)。
ユーザプログラムはこれらのマクロを
決して
直接定義すべきではない。
代わりに、上記のリストにある適切な機能検査マクロを利用すべきである。
下記のプログラムを使うと、各種の機能検査マクロが
glibc のバージョン
に応じてどのように設定されるかや、どの機能検査マクロが明示的に
設定されるか、を調べることができる。
以下に示すシェル・セッションは、
glibc 2.10
のシステムでの実行結果の例である。
$ cc ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 200809L
_BSD_SOURCE defined
_SVID_SOURCE defined
_ATFILE_SOURCE defined
$ cc -D_XOPEN_SOURCE=500 ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 199506L
_XOPEN_SOURCE defined: 500
$ cc -D_GNU_SOURCE ftm.c
$ ./a.out
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 200809L
_ISOC99_SOURCE defined
_XOPEN_SOURCE defined: 700
_XOPEN_SOURCE_EXTENDED defined
_LARGEFILE64_SOURCE defined
_BSD_SOURCE defined
_SVID_SOURCE defined
_ATFILE_SOURCE defined
_GNU_SOURCE defined
Program source¶
/* ftm.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
#ifdef _POSIX_SOURCE
printf("_POSIX_SOURCE defined\n");
#endif
#ifdef _POSIX_C_SOURCE
printf("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
#endif
#ifdef _ISOC99_SOURCE
printf("_ISOC99_SOURCE defined\n");
#endif
#ifdef _XOPEN_SOURCE
printf("_XOPEN_SOURCE defined: %d\n", _XOPEN_SOURCE);
#endif
#ifdef _XOPEN_SOURCE_EXTENDED
printf("_XOPEN_SOURCE_EXTENDED defined\n");
#endif
#ifdef _LARGEFILE64_SOURCE
printf("_LARGEFILE64_SOURCE defined\n");
#endif
#ifdef _FILE_OFFSET_BITS
printf("_FILE_OFFSET_BITS defined: %d\n", _FILE_OFFSET_BITS);
#endif
#ifdef _BSD_SOURCE
printf("_BSD_SOURCE defined\n");
#endif
#ifdef _SVID_SOURCE
printf("_SVID_SOURCE defined\n");
#endif
#ifdef _ATFILE_SOURCE
printf("_ATFILE_SOURCE defined\n");
#endif
#ifdef _GNU_SOURCE
printf("_GNU_SOURCE defined\n");
#endif
#ifdef _REENTRANT
printf("_REENTRANT defined\n");
#endif
#ifdef _THREAD_SAFE
printf("_THREAD_SAFE defined\n");
#endif
#ifdef _FORTIFY_SOURCE
printf("_FORTIFY_SOURCE defined\n");
#endif
exit(EXIT_SUCCESS);
}
関連項目¶
libc(7),
standards(7)
info libc の "Feature Test Macros"
の節。
/usr/include/features.h
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。