C -D_DEFAULT_源做什么?

C -D_DEFAULT_源做什么?,c,linux,gcc,gnu,bsd,C,Linux,Gcc,Gnu,Bsd,以前我收到来自gcc-std=c99的警告,提示usleep()被隐式声明。然后我偶然发现了,这使我使用了-D\u BSD\u SOURCE。但是,现在,gcc告诉我,-D\u BSD\u SOURCE已被弃用,我应该改用-D\u DEFAULT\u SOURCE #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" 为什么-D\u BSD\u SOURCE不推荐使用?为什么要改用-D\u DEF

以前我收到来自
gcc-std=c99
的警告,提示
usleep()
被隐式声明。然后我偶然发现了,这使我使用了
-D\u BSD\u SOURCE
。但是,现在,
gcc
告诉我,
-D\u BSD\u SOURCE
已被弃用,我应该改用
-D\u DEFAULT\u SOURCE

#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
为什么
-D\u BSD\u SOURCE
不推荐使用?为什么要改用
-D\u DEFAULT\u SOURCE
?它有什么作用

我做了,结果中充满了使用它来关闭
gcc
的人。我不知道为什么
-D\u BSD\u SOURCE
被弃用,事实就是如此。

描述了每个功能测试宏(FTM),包括
\u DEFAULT\u SOURCE

如果定义此宏,则大多数功能都包含在 X/Open、LFS和GNU扩展:其效果是从 POSIX的2008版,以及某些BSD和SVID功能 没有单独的功能测试宏来控制它们。定义这个 宏,且不使用编译器选项,如
-ansi
-std=c99
,与不定义任何特性测试宏具有相同的效果;将其与其他功能测试宏一起定义,或当选项 例如使用了
-ansi
,即使在其他 否则,选项将导致禁用它们

关于FTMs为我们提供了一个基本原理(以及其他可能有趣的信息):

最初的意图似乎是,在每个glibc中 使用FTM的头文件,只有一个
\uu使用\u*
内部 宏应该控制任何特定定义的公开。 此外,宏不应用于嵌套的
#ifdef
指令。对glibc头文件的检查很快表明 现实与本意相去甚远,这种情况导致罗兰 麦克格拉斯说,是时候进行一次大规模的清理了 事情恢复到预定的状态。罗兰认为这项任务可以完成 通过消除
\u BSD\u源
\u SVID\u源
FTM,可以简化, 尽管历史上他们有一个目的,但现在已经不复存在了 这些日子很有用。他说,再也不需要宏了 对于现代源代码来说,是那些与正式标准相关的代码
\u GNU\u源代码

Joseph Myers提供了一系列补丁来实现 这项工作的第一步。保守的方法受到了 罗兰的意思是对
\u BSD\u源代码的弃用
\u SVID\u SOURCE
FTMs正在两个glibc版本之间进行。版本 glibc的2.19增加了一个新的FTM,
\u DEFAULT\u SOURCE
。定义此宏会导致即使在显式 其他宏的定义将导致这种情况不会发生。效果 定义此宏的效果相当于显式 在早期glibc版本中定义三个宏:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C

因此,如果需要定义
\u BSD\u SOURCE
\u SVID\u SOURCE
,也只需定义
\u DEFAULT\u SOURCE
。glibc版本我需要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

这件事发生在年。至于它的功能,在头文件unistd.h中定义了.usleep()函数。但是,根据手册页,它已被淘汰,取而代之的是使用nanosleep。函数nanosleep()在头文件time.h中定义,还有链接步骤。对于gcc,需要'-lrt'parameter@user3629249这表明新的应用程序开发不需要指定-lrt,但我现在已经转到nanosleep()。当然,真正的解决办法是避免不推荐的
usleep
(如果可能的话),而是使用它,因为单一的Unix规范没有删除它。@ChronoKitsune:是的,我写了一些关于这方面的东西,但他没有问这个具体的案例,因此没有在答案中结束。要将
nanosleep()
-std=c99
一起使用,还必须定义FTM,但至少它是POSIX!