“#define _GNU_SOURCE”是什么意思?意味着?
今天我必须使用 basename()
函数和 man 3 basename
(这里)给了我一些奇怪的消息:
注释
basename() 有两个不同的版本 - 上面描述的 POSIX 版本,以及 GNU 版本,后者是在 < /p>
#define _GNU_SOURCE
#include
我想知道这个 #define _GNU_SOURCE
意味着什么:它是否污染我用 GNU 编写的代码相关许可证?或者它只是用来告诉编译器类似“好吧,我知道,这组函数不是 POSIX,因此不可移植,但我还是想使用它”。
如果是这样,为什么不给人们不同的标头,而不是必须定义一些晦涩的宏来获得一个函数实现或另一个函数实现?
还有一些事情让我烦恼:编译器如何知道哪个函数实现与可执行文件链接?它也使用这个#define
吗?
有人可以给我一些指示吗?
Today I had to use the basename()
function, and the man 3 basename
(here) gave me some strange message:
Notes
There are two different versions of basename() - the POSIX version described above, and the GNU version, which one gets after
#define _GNU_SOURCE
#include <string.h>
I'm wondering what this #define _GNU_SOURCE
means: is it tainting the 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".
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 #define
as well?
Anybody have some pointers to give me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
定义
_GNU_SOURCE
与许可证无关,与编写(非)可移植代码有关。如果您定义_GNU_SOURCE
,您将获得:mount
、ifconfig
等系统实用程序。只要您了解这些事情,定义
_GNU_SOURCE
应该不是问题,但您应该避免定义它,而是定义_POSIX_C_SOURCE=200809L
或>_XOPEN_SOURCE=700
尽可能确保您的程序可移植。特别是,您永远不应该使用
_GNU_SOURCE
中的内容是上面的 #2 和 #4。Defining
_GNU_SOURCE
has nothing to do with license and everything to do with writing (non-)portable code. If you define_GNU_SOURCE
, you will get:mount
,ifconfig
, etc.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=200809L
or_XOPEN_SOURCE=700
when possible to ensure that your programs are portable.In particular, the things from
_GNU_SOURCE
that you should never use are #2 and #4 above.有关
_GNU_SOURCE
启用的功能的确切详细信息,文档可以提供帮助。来自 GNU 文档:
从 功能测试宏 上的 Linux 手册页:
注意:在包含头文件之前需要定义
_GNU_SOURCE
,以便各个头文件启用这些功能。例如:还可以使用
-D
标志在每次编译时启用_GNU_SOURCE
:(-D
并非特定于_GNU_SOURCE 但任何宏都可以这样定义)。
For exact details on what are all enabled by
_GNU_SOURCE
, documentation can help.From the GNU documentation:
From the Linux man page on feature test macros:
Note:
_GNU_SOURCE
needs to be defined before including header files so that the respective headers enable the features. For example:_GNU_SOURCE
can be also be enabled per compilation using-D
flag:(
-D
is not specific to_GNU_SOURCE
but any macro be defined this way).我再回答两点:
一种常见的方法是有条件地将
#define
标识符basename
指定为不同的名称,具体取决于是否定义了_GNU_SOURCE
。例如:现在库只需要在这些名称下提供这两种行为。
通常,相同的标头在不同的 Unix 版本中具有稍微不同的内容,因此没有单一的正确内容,例如
— 有许多标准 (xkcd)。有一整套宏可供选择您最喜欢的宏,因此,如果您的程序需要一个标准,则该库将符合该标准。
Let me answer two further points:
A common approach is to conditionally
#define
identifierbasename
to different names, depending on whether_GNU_SOURCE
is defined. For instance:Now the library simply needs to provide both behaviors under those names.
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.
来自谷歌的一些邮件列表:
因此它为 gcc 启用了大量编译标志
From some mailing list via google:
So it enables a whole lot of compiling flags for gcc
他们已经有了;标题按主题分为文件,因此需要另一个维度来过滤。
我正在寻找信号数字到名称的转换。我在
中找到了strsignal()
。手册页上写着:我从来没有真正关心过这部分。
sigabbrev_np()
不包含在默认“功能”中。string.h
显示了如何:__USE_GNU
可以/应该通过_GNU_SOURCE
在编译时或文件顶部进行设置。但这也会“激活”所有标头中的所有其他此类 ifdefed 声明。 (除非您为每个标头定义/取消定义)因此,要显式导入仅一个(或其他)特殊函数,我现在这样做(复制粘贴。我留下了“THROW”并更改了“ __sig"):
现在
sigabbrev_np(wstate >> 8)
给我TRAP
等,无需#defines。我很难意识到
0x57f
意味着 OK,因为5
是TRAP
,但是0xb7f
和0x77f
是SEGV
和BUS
--- 我得到的取决于我设置断点的位置,有时是在数千条指令之后。因为我没有后退指令指针......They already got them; the headers are divided by topic into files, so it takes another dimension to filter.
I was looking for a signal number-to-name conversion. I found
strsignal()
, in<string.h>
. The man page says:I had never really cared for this part at all.
sigabbrev_np()
is not included in the default "features".string.h
shows how:__USE_GNU
can/should be set via_GNU_SOURCE
, at compilation or top of the file. But that "activates" all other such ifdeffed declarations in all headers, too. (Unless you define-undefine per header)So to explicitly import just one (or the other) special function, I go like this for now (copy-paste. I left the "THROW" and changed "__sig"):
Now
sigabbrev_np(wstate >> 8)
gives meTRAP
etc. without #defines.I had a hard time realizing that
0x57f
means OK because5
isTRAP
, but0xb7f
and0x77f
areSEGV
andBUS
--- which I got depending on where I set the breakpoint, sometimes after thousands of instructions. Because I did not step back the intruction pointer...