今日はbasename()
関数を使用する必要があり、man 3 basename
( here )は奇妙なメッセージをくれました:
注
basename()-上記のPOSIXバージョンとGNUバージョン、後に取得
#define _GNU_SOURCE
#include <string.h>
私はこの#define _GNU_SOURCE
が何を意味するのか疑問に思っています。それはtainting私がGNU関連のライセンスで書いたコードですか?または、単にコンパイラに「まあ、この関数のセットはPOSIXではないので移植性がありませんが、とにかく使用したい」のようなものを伝えるために使用されます。
もしそうなら、なんらかの関数の実装を取得するためにいくつかのあいまいなマクロを定義する代わりに、人々に異なるヘッダーを与えないのはなぜですか?
また、何かバグがあります。コンパイラーは、どの関数実装を実行可能ファイルとリンクするかをどのように知るのですか?この#define
も使用しますか?
誰か私に教えてくれるポインターがありますか?
_GNU_SOURCE
を定義することは、ライセンスとは無関係であり、(非)移植性のあるコードを書くことに関係します。 _GNU_SOURCE
を定義すると、以下が得られます:
mount
、ifconfig
などのシステムユーティリティを実装するために必要な低レベル関数へのアクセス.これらのことを知っている限り、_GNU_SOURCE
を定義することは問題ではありませんが、定義を避け、代わりに_POSIX_C_SOURCE=200809L
または_XOPEN_SOURCE=700
を定義して、プログラムは移植可能です。
特に、_GNU_SOURCE
からneverを使用する必要があるものは、上記の#2と#4です。
さらに2つのポイントに答えてみましょう。
また、何かバグがあります。コンパイラーは、どの関数実装を実行可能ファイルとリンクするかをどのように知るのですか?この#defineも使用しますか?
一般的なアプローチは、#define
が定義されているかどうかに応じて、異なる名前に_GNU_SOURCE
識別子basename
を条件付きで付けることです。例えば:
#ifdef _GNU_SOURCE
# define basename __basename_gnu
#else
# define basename __basename_nongnu
#endif
これで、ライブラリはこれらの名前で両方の動作を提供するだけで済みます。
もしそうなら、なんらかの関数実装を取得するためにいくつかのあいまいな環境変数を定義する代わりに、人々に異なるヘッダーを与えないのはなぜですか?
多くの場合、同じヘッダーは異なるUnixバージョンでわずかに異なるコンテンツを持っていたので、たとえば<string.h>
には単一の正しいコンテンツはありません—多くの標準があります( xkcd )。お気に入りのマクロを選択するための一連のマクロがあるため、プログラムが1つの標準を想定している場合、ライブラリはそれに準拠します。
_GNU_SOURCE
によってすべて有効になるものの詳細については、ドキュメントが役立ちます。
GNUドキュメントから:
マクロ:_GNU_SOURCE
このマクロを定義すると、ISO C89、ISO C99、POSIX.1、POSIX.2、BSD、SVID、X/Open、LFS、およびGNU拡張のすべてが含まれます。 POSIX.1がBSDと競合する場合、POSIX定義が優先されます。
機能テストマクロ のLinux manページから:
_GNU_SOURCE
(任意の値で)このマクロを定義すると、_ATFILE_SOURCE、_LARGEFILE64_SOURCE、_ISOC99_SOURCE、_XOPEN_SOURCE_EXTENDED、_POSIX_SOURCE、_POSIX_C_SOURCEの値が200809L(2.10より前のglibcバージョンで200112L; glibcバージョン2.5より前の199309L; 199309Lで199309Lの前に)値が700の_XOPEN_SOURCE(2.10より前のglibcバージョンでは600、2.2より前のglibcバージョンでは500)。さらに、さまざまなGNU固有の拡張機能も公開されています。
Glibc 2.19以降、_GNU_SOURCEを定義すると、_DEFAULT_SOURCEを暗黙的に定義する効果もあります。 2.20以前のglibcバージョンでは、_GNU_SOURCEを定義すると、_BSD_SOURCEおよび_SVID_SOURCEを暗黙的に定義する効果もありました。
注:_GNU_SOURCE
を定義する必要がありますbeforeヘッダーを含む各ヘッダーで機能を有効にするためのファイル。例えば:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
...
_GNU_SOURCE
は、-D
フラグを使用してコンパイルごとに有効にすることもできます。
$ gcc -D_GNU_SOURCE file.c
(-D
は_GNU_SOURCE
に固有ではありませんが、このようにマクロを定義します)。
Google経由のメーリングリストから:
Glibcのinclude/features.hを見てください。
_GNU_SOURCE上記のすべてに加えて、GNU拡張機能。
つまり、これはすべてこれを可能にします:
STRICT_ANSI、_ ISOC99_SOURCE、_POSIX_SOURCE、_POSIX_C_SOURCE、_XOPEN_SOURCE、_XOPEN_SOURCE_EXTENDED、_LARGEFILE_SOURCE、_LARGEFILE64_SOURCE、_FILE_OFFSET_BITS = N、_BSD_SOURCE、_SVID_SOURCE
そのため、gccの多くのコンパイルフラグが有効になります。