C语言 “#define _GNU_SOURCE”是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5582211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does "#define _GNU_SOURCE" imply?
提问by Gui13
Today I had to use the basename()function, and the man 3 basename(here) gave me some strange message:
今天我不得不使用这个basename()函数,man 3 basename(这里)给了我一些奇怪的信息:
Notes
There are two different versions of basename()- the POSIXversion described above, and the GNU version, which one gets after
#define _GNU_SOURCE#include <string.h>
笔记
basename()有两种不同的版本——上面描述的POSIX版本和GNU 版本,后者是后者
#define _GNU_SOURCE#include <string.h>
I'm wondering what this #define _GNU_SOURCEmeans: is it taintingthe code I write with a GNU-related license? Or is it simply used to tell the compiler something like "Well, I know, this set of functions is not POSIX, thus not portable, but I'd like to use it anyway".
我想知道这#define _GNU_SOURCE意味着什么:它是否污染了我使用 GNU 相关许可证编写的代码?或者它只是用来告诉编译器类似“好吧,我知道,这组函数不是 POSIX,因此不可移植,但我还是想使用它”。
If so, why not give people different headers, instead of having to define some obscure macro to get one function implementation or the other?
如果是这样,为什么不给人们不同的标题,而不必定义一些晦涩的宏来获得一个函数实现或另一个?
Something also bugs me: how does the compiler know which function implementation to link with the executable? Does it use this #defineas well?
我也有一些问题:编译器如何知道哪个函数实现与可执行文件链接?它也使用这个#define吗?
Anybody have some pointers to give me?
有人给我一些指示吗?
回答by R.. GitHub STOP HELPING ICE
Defining _GNU_SOURCEhas nothing to do with license and everything to do with writing (non-)portable code. If you define _GNU_SOURCE, you will get:
定义_GNU_SOURCE与许可证无关,而与编写(非)可移植代码有关。如果你定义了_GNU_SOURCE,你会得到:
- access to lots of nonstandard GNU/Linux extension functions
- access to traditional functions which were omitted from the POSIX standard (often for good reason, such as being replaced with better alternatives, or being tied to particular legacy implementations)
- access to low-level functions that cannot be portable, but that you sometimes need for implementing system utilities like
mount,ifconfig, etc. - broken behavior for lots of POSIX-specified functions, where the GNU folks disagreed with the standards committee on how the functions should behave and decided to do their own thing.
- 访问大量非标准的 GNU/Linux 扩展功能
- 访问 POSIX 标准中省略的传统功能(通常有充分的理由,例如被更好的替代品取代,或与特定的遗留实现相关联)
- 获得低级别的功能,可以是便携式的,但有时需要实现系统工具一样
mount,ifconfig等等。 - 许多 POSIX 指定函数的破坏行为,在这些函数中,GNU 人员不同意标准委员会关于函数的行为方式,并决定做自己的事情。
As long as you're aware of these things, it should not be a problem to define _GNU_SOURCE, but you should avoid defining it and instead define _POSIX_C_SOURCE=200809Lor _XOPEN_SOURCE=700when possible to ensure that your programs are portable.
只要您知道这些事情,定义 应该不是问题_GNU_SOURCE,但是您应该避免定义它,而是在可能的情况下定义_POSIX_C_SOURCE=200809L或_XOPEN_SOURCE=700以确保您的程序是可移植的。
In particular, the things from _GNU_SOURCEthat you should neveruse are #2 and #4 above.
特别是,_GNU_SOURCE你永远不应该使用的东西是上面的#2 和#4。
回答by Blaisorblade
Let me answer two further points:
我再回答两点:
Something also bugs me: how does the compiler know which function implementation to link with the executable? Does it use this #define as well?
我也有一些问题:编译器如何知道哪个函数实现与可执行文件链接?它是否也使用这个#define?
A common approach is to conditionally #defineidentifier basenameto different names, depending on whether _GNU_SOURCEis defined. For instance:
一种常见的方法是有条件地将#define标识符标识basename为不同的名称,这取决于是否_GNU_SOURCE已定义。例如:
#ifdef _GNU_SOURCE
# define basename __basename_gnu
#else
# define basename __basename_nongnu
#endif
Now the library simply needs to provide both behaviors under those names.
现在库只需要在这些名称下提供这两种行为。
If so, why not give people different headers, instead of having to define some obscure environment variable to get one function implementation or the other?
如果是这样,为什么不给人们不同的标题,而不必定义一些晦涩的环境变量来获得一个函数实现或另一个?
Often the same header had slightly different contents in different Unix versions, so there is no single right content for, say, <string.h>— there are many standards (xkcd).
There's a whole set of macros to pick your favorite one, so that if your program expects one standard, the library will conform to that.
通常,相同的头文件在不同的 Unix 版本中的内容略有不同,因此没有单一的正确内容,例如<string.h>- 有许多标准 ( xkcd)。有一整套宏可以选择您最喜欢的宏,因此如果您的程序需要一个标准,库将符合该标准。
回答by P.P
For exact details on what are all enabled by _GNU_SOURCE, documentation can help.
有关所有启用内容的确切详细信息_GNU_SOURCE,文档可以提供帮助。
From the GNU documentation:
来自 GNU 文档:
Macro: _GNU_SOURCE
If you define this macro, everything is included: ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X/Open, LFS, and GNU extensions. In the cases where POSIX.1 conflicts with BSD, the POSIX definitions take precedence.
宏:_GNU_SOURCE
如果您定义此宏,则包括所有内容:ISO C89、ISO C99、POSIX.1、POSIX.2、BSD、SVID、X/Open、LFS 和 GNU 扩展。在 POSIX.1 与 BSD 冲突的情况下,POSIX 定义优先。
From the Linux man page on feature test macros:
从 Linux 手册页上的功能测试宏:
_GNU_SOURCE
Defining this macro (with any value) implicitly defines _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE, _POSIX_C_SOURCE with the value 200809L (200112L in glibc versions before 2.10; 199506L in glibc versions before 2.5; 199309L in glibc ver‐ sions before 2.1) and _XOPEN_SOURCE with the value 700 (600 in glibc versions before 2.10; 500 in glibc versions before 2.2). In addition, various GNU-specific extensions are also exposed.
Since glibc 2.19, defining _GNU_SOURCE also has the effect of implicitly defining _DEFAULT_SOURCE. In glibc versions before 2.20, defining _GNU_SOURCE also had the effect of implicitly defining _BSD_SOURCE and _SVID_SOURCE.
_GNU_SOURCE
定义该宏(任意值)隐式地定义_ATFILE_SOURCE,_LARGEFILE64_SOURCE,_ISOC99_SOURCE,_XOPEN_SOURCE_EXTENDED,_POSIX_SOURCE,_POSIX_C_SOURCE用值200809L(200112L在glibc的版本前2.10;在glibc的版本199506L之前2.5;在glibc的版本2.1之前199309L)和_XOPEN_SOURCE 值为 700(在 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 的效果。
Note: _GNU_SOURCEneeds to be defined beforeincluding header files so that the respective headers enable the features. For example:
注意:_GNU_SOURCE需要在包含头文件之前定义,以便相应的头文件启用功能。例如:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
...
_GNU_SOURCEcan be also be enabled per compilation using -Dflag:
_GNU_SOURCE也可以使用-D标志在每次编译时启用:
$ gcc -D_GNU_SOURCE file.c
(-Dis not specific to _GNU_SOURCEbut any macro be defined this way).
(-D不是特定于_GNU_SOURCE但任何宏都可以通过这种方式定义)。
回答by Chris
From some mailing list via google:
来自谷歌的一些邮件列表:
Look at glibc's include/features.h:
_GNU_SOURCE All of the above, plus GNU extensions.
Which means it enables all this:
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
查看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_BSOURCE_SV
So it enables a whole lot of compiling flags for gcc
所以它为 gcc 启用了大量的编译标志

