FEATURE_TEST_MACROS(7) | Linux Programmer's Manual | FEATURE_TEST_MACROS(7) |
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 /* 500 未満の任意の値 */
別の方法としては、等価な定義をコンパイル用のコマンドで 指定することもできる。
cc -D_BSD_SOURCE cc -D_XOPEN_SOURCE # 500 未満の任意の値
後で述べるが、 「いくつかの機能検査マクロはデフォルトで定義される」 点に注意すること。 このため、「書式」に記載された機能検査マクロを常に 明示的に指定する必要があるわけではない。
あまり多くないが、マニュアルページによっては、 機能検査マクロの要件を以下のように簡単な表現で記載する場合がある。 (以下の例は readahead(2) のマニュアルページからの引用である)。
#define _GNU_SOURCE #include <fcntl.h> ssize_t readahead(int fd, off64_t *offset, size_t count);
関数定義の公開に使える機能検査マクロが一つだけで、 デフォルトではそのマクロが定義されない場合に、 この形式の表現を利用する。
以下では、Linux glibc 2.x (x > 0) において、 機能検査マクロがどのように扱われるかを説明する。
Linux/glibc は以下の機能検査マクロを解釈する:
初期のバージョン 2.1.x の glibc では、これと等価な _ISOC9X_SOURCE という名前のマクロが使われていた (なぜなら、C99 標準はまだ確定していなかったからである)。 _ISOC9X_SOURCE マクロの使用は廃止されているが、 glibc は過去との互換性のため今でもこのマクロを認識する。
_ISOC99_SOURCE を定義すると、 ISO C (1990) Amendment 1 ("C95") の定義も公開される (C95 での主要な変更点は国際化文字集合のサポートであった)。
64 ビットシステムは、もともと 2 ギガバイトより大きなファイルを 扱えるので、64 ビットシステムではこのマクロは効果を持たない。
バージョン 2.18 以前の glibc では、このマクロを定義すると、相容れない標準が存在する状況において BSD 由来の定義を優先するようになる。 ただし、 _SVID_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _GNU_SOURCE が一つでも定義された場合には、BSD 由来の定義は優先されなくなる。 glibc 2.19 以降では、 _BSD_SOURCE を定義しても相容れない標準があっても BSD 由来の定義が優先されることはもはやなくなった。
glibc 2.20 以降では、このマクロは非推奨である。 このマクロは現在は _DEFAULT_SOURCE を定義するのと同じ効果を持つが、 (_DEFAULT_SOURCE が合わせて定義されていない場合には) コンパイル時の警告が出る。 代わりに _DEFAULT_SOURCE を使用すること。 glibc 2.19 以前で _BSD_SOURCE が必要で glibc 2.20 以降で _DEFAULT_SOURCE を必要とするプログラムを警告を出さずにコンパイルするには、 _BSD_SOURCE と _DEFAULT_SOURCE の両方を定義すること。
glibc 2.20 以降、 _BSD_SOURCE と同様にこのマクロは非推奨となっている。
「デフォルト」定義は、 POSIX.1-2008 で必須となっている定義と、 BSD と System V 由来の種々の定義を公開する。 glibc 2.19 以前では、これらのデフォルトは以下を明示的に定義するのとほぼ等価である。
cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809
glibc 2.19 以降では、 _GNU_SOURCE を定義すると、 _DEFAULT_SOURCE も暗黙のうちに定義される。 バージョン 2.20 より前の glibc では、 _GNU_SOURCE を定義すると、 _BSD_SOURCE と _SVID_SOURCE も暗黙のうちに定義されていた。
ついてだけである。 現在の実装では、以下の関数にチェックが追加されている: 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 (glibc 2.19 以前), _SVID_SOURCE (glibc 2.19 以前), _DEFAULT_SOURCE (glibc 2.19 以降), _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 (glibc 2.19 以前), _SVID_SOURCE (glibc 2.19 以前) のいずれかが明示的に定義された場合、 _BSD_SOURCE, _SVID_SOURCE, _SVID_SOURCE はデフォルトでは定義されない。
_POSIX_SOURCE と _POSIX_C_SOURCE が明示的に定義されない場合で、 __STRICT_ANSI__ が定義されない、もしくは _XOPEN_SOURCE が 500 以上の値で定義されたときには、
また、複数のマクロを定義することもできる。 この場合、定義したマクロはすべて有効になる。
POSIX.1 では _POSIX_C_SOURCE, _POSIX_SOURCE, _XOPEN_SOURCE が規定されている。 _XOPEN_SOURCE_EXTENDED は XPG4v2 (別名 SUSv1) で規定されていた。
_FILE_OFFSET_BITS はどの標準でも規定されていないが、 他のいくつかの実装で採用されている。
_BSD_SOURCE, _SVID_SOURCE, _DEFAULT_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
/* 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 _ISOC11_SOURCE
printf("_ISOC11_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 _DEFAULT_SOURCE
printf("_DEFAULT_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); }
info libc の "Feature Test Macros" の節。
/usr/include/features.h
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2014-03-20 | Linux |