“-D_DEFAULT_SOURCE”是什么意思?

36

之前我收到了来自gcc -std=c99的警告,指出usleep()已被隐式声明。后来我偶然发现了这个stackoverflow帖子,它让我使用了-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? 它的作用是什么?

我进行了一些谷歌搜索,结果只是装作使用它来让 gcc 安静下来。 我找不到为什么 -D_BSD_SOURCE 被弃用了,只知道它被弃用了。


2
它发生在glibc 2.20中。至于它的作用,glibc文档解释了其预期效果 - user539810
usleep()函数定义在头文件unistd.h中,但根据man页面,它已经过时了,应该使用nanosleep代替。函数nanosleep()定义在头文件time.h中。此外,对于gcc的链接步骤,需要使用“-lrt”参数。 - user3629249
@user3629249 这个librt的man页面建议“新应用程序开发不需要指定-lrt”,但是我现在已经转向使用nanosleep()了。 - ryanmjacobs
2个回答

31

glibc手册详细介绍了每个特性测试宏(FTM),包括_DEFAULT_SOURCE

如果定义此宏,则会包含大多数特性,除了X / Open,LFS和GNU扩展:其效果是启用来自POSIX 2008版的功能,以及某些BSD和SVID功能,而无需单独的特性测试宏来控制它们。仅定义此宏,而不使用编译器选项(如-ansi-std=c99)具有与未定义任何特性测试宏相同的效果;与其他特性测试宏一起定义它,或者在使用-ansi等选项时定义它,即使其他选项会导致禁用它们,也会启用这些功能。

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

The original intent seems to have been that, within each of the glibc header files that employs FTMs, only one of the __USE_* internal macros should govern the exposure of any particular definition. Additionally, the macros should not be used in nested #ifdef directives. An inspection of the glibc header files quickly shows that the reality is far from the intent, a situation that led Roland McGrath to suggest that it was time for a major cleanup to bring things back to the intended situation. Roland thought that task could be simplified by eliminating the _BSD_SOURCE and _SVID_SOURCE FTMs, which, although they had a purpose historically, have ceased to be useful these days. Anymore, he said, the only macros that are needed for modern source code are those that relate to formal standards plus _GNU_SOURCE.

Joseph Myers duly obliged with a series of patches to implement the first steps in this work. The conservative approach encouraged by Roland meant that the deprecation of the _BSD_SOURCE and _SVID_SOURCE FTMs is taking place across two glibc versions. Version 2.19 of glibc added a new FTM, _DEFAULT_SOURCE. Defining this macro causes the default definitions to be exposed even when the explicit definition of other macros would cause that not to happen. The effect of defining this macro is equivalent to the effect of explicitly defining three macros in earlier glibc versions:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C
因此,如果您需要定义_BSD_SOURCE_SVID_SOURCE,只需同时定义_DEFAULT_SOURCE即可。 glibc版本<= 2.18不关心它,而版本>= 2.19不会警告如果定义了两个或所有三个源。

1
当然,真正的解决方法是避免使用已弃用的 usleep(如果可能的话),而是使用 nanosleep。因为 Single Unix 规范并没有将其删除。 - user539810
4
@ChronoKitsune: 是的,我写了一些关于这个问题的内容,但他没有问到这个特定的情况,所以它没有出现在答案中。如果要使用nanosleep()-std=c99,你还需要定义一个FTM,但至少它是POSIX标准的。 - cremno

6
我需要的是超越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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接