-D_DEFAULT_SOURCE做什么?

rya*_*obs 21 c linux bsd gcc gnu

从以前我收到了警告,gcc -std=c99usleep()是隐式声明.然后我偶然发现了这个stackoverflow帖子,这让我使用了-D_BSD_SOURCE.但是,现在gcc告诉我-D_BSD_SOURCE已经弃用了,我应该使用-D_DEFAULT_SOURCE.

#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Run Code Online (Sandbox Code Playgroud)

为什么-D_BSD_SOURCE弃用?为什么-D_DEFAULT_SOURCE用呢?它做了什么?

我做了一些谷歌搜索,结果只是让人们用它来闭嘴gcc.我无法找到为什么 -D_BSD_SOURCE被弃用,只是它已经被弃用了.

cre*_*mno 15

所述的glibc手册描述了每个功能测试宏(FTM),包括_DEFAULT_SOURCE:

如果你定义这个宏,大多数功能都包含在X/Open,LFS和GNU扩展中:效果是启用2008版POSIX的功能,以及某些BSD和SVID功能,而无需单独的功能测试宏来控制他们.单独定义此宏并且不使用诸如-ansi或之类的 编译器选项-std=c99与不定义任何特征测试宏具有相同的效果; 将其与其他功能测试宏一起定义,或者在-ansi使用诸如使用的选项时,即使其他选项会导致它们被禁用,也会启用这些功能.

这篇 关于FTM的LWN.net文章为我们提供了一个基本原理(其中可能还有一些有趣的信息):

最初的意图似乎是,在使用FTM的每个glibc头文件中,只有一个__USE_*内部宏应该控制任何特定定义的暴露.此外,不应在嵌套#ifdef 指令中使用宏.对glibc头文件的快速检查表明,现实远非意图,这种情况导致Roland McGrath 认为是时候进行大规模清理以使事情恢复到预期的状态.罗兰认为,通过消除_BSD_SOURCE_SVID_SOURCEFTM 可以简化任务,虽然它们在历史上有一个目的,但这些天已经不再有用了.他说,现代源代码所需的唯一宏是与正式标准相关的宏 _GNU_SOURCE.

约瑟夫迈尔斯正式承担了一系列补丁,以实施这项工作的第一步.罗兰鼓励保守的做法意味着的折旧_BSD_SOURCE_SVID_SOURCEFTMS跨两个版本的glibc的发生.glibc 2.19版增加了一个新的FTM _DEFAULT_SOURCE.定义此宏会导致默认定义暴露,即使其他宏的显式定义会导致不发生这种定义.定义此宏的效果等同于在早期glibc版本中显式定义三个宏的效果:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C
Run Code Online (Sandbox Code Playgroud)

因此,如果您需要定义_BSD_SOURCE_SVID_SOURCE简单定义_DEFAULT_SOURCE.glibc版本<= 2.18不关心它,版本> = 2.19如果定义了两个或全部三个,则不会发出警告.

  • @ChronoKitsune:是的,我已经写了一些关于这个问题,但是他没有询问这个具体案例,因此它没有在答案中结束.要使用`-std = c99`的`nanosleep()`,你还必须定义一个FTM,但至少它是一个POSIX! (3认同)

Pau*_*xie 7

我需要超越 linux 和 glibc 的可移植性,而且我不喜欢 #ifdef。所以:

/* asprintf() does not appear on linux without this */
#define _GNU_SOURCE

/* gettimeofday() does not appear on linux without this. */
#define _BSD_SOURCE

/* modern glibc will complain about the above if it doesn't see this. */
#define _DEFAULT_SOURCE
Run Code Online (Sandbox Code Playgroud)