这个简单的.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文件中放入声明来以一种拙劣的方式实现这一点。
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.h
(隐式地包含在unistd.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
。 这意味着你不能从unistd.h
获得gethostname
,除非你再次定义_BSD_SOURCE
。 我通常将_GNU_SOURCE放置在我的命令行(即gcc -D_GNU_SOURCE -std=c99 file.c
)上,这也是大部分的事情,它也打开了_BSD_SOURCE
。
PS手册页包含一个可打印当前ft-macros的示例程序。 您可以编译并运行一些编译器设置。