Linux上的unistd.h和c99

sli*_*lim 11 c unix linux c99

这个简单的.c文件:

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}
Run Code Online (Sandbox Code Playgroud)

...正常编译时,工作正常:

$ cc  -Wall -c -o tmp.o tmp.c
$
Run Code Online (Sandbox Code Playgroud)

...但是在C99模式下编译时,会发出警告:

$ cc -Wall -std=c99 -c -o tmp.o tmp.c 
tmp.c: In function `test':
tmp.c:5: warning: implicit declaration of function `gethostname'
$
Run Code Online (Sandbox Code Playgroud)

结果.o文件很好,链接工作.我只是想摆脱警告.我可以通过在我自己的.h文件中添加声明来以一种hacky方式实现这一点.

什么是C99,这意味着unistd.h中的声明不包括在内?这可以克服,而不放弃C99的优点吗?

我看到其他标准库存在同样的问题.

Mic*_*urr 17

您可能需要以特定的方式定义一些宏来获取原型 gethostname()

来自man gethostname:

glibc的功能测试宏要求(参见feature_test_macros(7)):

   gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
   sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
Run Code Online (Sandbox Code Playgroud)

所以:

#define _BSD_SOURCE

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}
Run Code Online (Sandbox Code Playgroud)

血腥的细节:

如果您未指定该-std-c99选项,则features.h(unistd.h默认包含该选项)将默认设置_BSD_SOURCEgethostname()包含原型.但是,指定-std=c99会导致编译器自动定义__STRICT_ANSI__,这反过来导致features.h不定义_BSD_SOURCE,除非您使用自己的功能宏定义(如上所述)强制它.


Ste*_*non 10

gethostname( ) 不是标准的C函数(在C99标准中没有提到它),因此在编译到标准时没有正确定义符号.

如果您正在使用gcc工具链,请使用-std=gnu99,您将获得所需的行为.

或者,看一下<features.h>,似乎你可以使用-D_GNU_SOURCE-D_XOPEN_SOURCE=500获得所需的行为.


Nor*_*ame 5

man gethostname。它在功能测试宏要求中表示,需要_BSD_SOURCE(或_XOPEN_SOURCE>500) 从 unistd.h 中提取 gethostname。

接下来阅读man feature_test_macros。你会发现哪个-std=c99打开__STRICT_ANSI__哪个关闭 _BSD_SOURCE。这意味着除非您再次定义,否则您无法从中gethostname获取。对于大多数事情,我通常将 _GNU_SOURCE 放在我的命令行(即 )上,它也会打开。unistd.h_BSD_SOURCEgcc -D_GNU_SOURCE -std=c99 file.c_BSD_SOURCE

PS 手册页包含一个示例程序,可以打印当前的 ft 宏。您可以针对某些编译器设置编译并运行它。