之前我收到了来自gcc -std=c99
的警告usleep()
被隐含声明。然后我偶然发现this stackoverflow post,这导致我使用-D_BSD_SOURCE
。但是,现在gcc
告诉我,-D_BSD_SOURCE
已弃用,我应该使用-D_DEFAULT_SOURCE
。
#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
为什么-D_BSD_SOURCE
已被弃用?为什么要使用-D_DEFAULT_SOURCE
?它做了什么?
我做了some googling,结果只是让人们用它来关闭gcc
。我找不到为什么 -D_BSD_SOURCE
已被弃用,只是它已被弃用。
答案 0 :(得分:15)
glibc manual描述了每个功能测试宏(FTM),包括_DEFAULT_SOURCE
:
关于FTM的如果您定义此宏,则大多数功能都包含在内 X / Open,LFS和GNU扩展:效果是启用功能 2008版POSIX,以及某些BSD和SVID功能 没有单独的功能测试宏来控制它们。定义这个 宏,单独使用而不使用
-ansi
或。{}等编译器选项-std=c99
,与不定义任何特征测试宏具有相同的效果;将其与其他功能测试宏一起定义,或者在选项时定义它 例如使用-ansi
,即使在另一个时也启用这些功能 选项会导致它们被禁用。
This LWN.net article为我们提供了一个基本原理(其中可能还有一些有趣的信息):
最初的意图似乎是在每个glibc中 使用FTM的头文件,只有
__USE_*
内部的一个 宏应该控制任何特定定义的暴露。 此外,不应在嵌套#ifdef
中使用宏 指令。对glibc头文件的检查可以快速显示出来 现实远非意图,导致罗兰的情况 McGrath to suggest现在是时候进行重大清理了 回到预期的情况。罗兰认为任务可以 通过消除_BSD_SOURCE
和_SVID_SOURCE
FTM简化, 虽然它们在历史上有一个目的,但已不复存在 这些天很有用。他说,只需要唯一的宏 现代源代码是那些与正式标准相关的代码_GNU_SOURCE
。Joseph Myers duly obliged带有一系列补丁来实现 这项工作的第一步。鼓励的保守方法 罗兰意味着
_BSD_SOURCE
和{。}的弃用_SVID_SOURCE
FTM正在两个glibc版本中发生。版 glibc 2.19增加了一个新的FTM,_DEFAULT_SOURCE
。定义此宏会导致默认定义即使在显式时也会公开 其他宏的定义会导致不会发生。效果 定义此宏等效于显式的效果 在早期的glibc版本中定义三个宏:cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C
因此,如果您需要定义_BSD_SOURCE
或_SVID_SOURCE
,也可以定义_DEFAULT_SOURCE
。 glibc版本< = 2.18不关心它,版本> = 2.19如果定义了两个或所有三个版本,则不会发出警告。
答案 1 :(得分:1)
我需要超越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