繁体   English   中英

Linux上的unistd.h和c99

[英]unistd.h and c99 on Linux

这个简单的.c文件:

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

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

$ cc  -Wall -c -o tmp.o tmp.c
$

...但是在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'
$

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

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

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

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

来自man gethostname

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

  gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) 

所以:

#define _BSD_SOURCE

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

血腥的细节:

如果未指定-std-c99选项,则features.hunistd.h隐式包含)将默认设置_BSD_SOURCE ,以便包含gethostname()的原型。 但是,指定-std=c99会导致编译器自动定义__STRICT_ANSI__ ,这会导致features.h无法定义_BSD_SOURCE ,除非您使用自己的功能宏定义强制它(如上所述)。

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

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

或者,查看<features.h> ,您似乎可以使用-D_GNU_SOURCE-D_XOPEN_SOURCE=500来获得所需的行为。

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

接下来阅读man feature_test_macros 你会发现-std=c99打开__STRICT_ANSI__ ,它关闭 _BSD_SOURCE 这意味着除非再次定义_BSD_SOURCE ,否则无法从unistd.h获取gethostname 我通常在我的命令行上放置_GNU_SOURCE(即gcc -D_GNU_SOURCE -std=c99 file.c )以获取大多数内容,这_BSD_SOURCE打开_BSD_SOURCE

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM