这个简单的.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)):
Run Code Online (Sandbox Code Playgroud)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);
}
Run Code Online (Sandbox Code Playgroud)
血腥的细节:
如果您未指定该-std-c99
选项,则features.h
(unistd.h
默认包含该选项)将默认设置_BSD_SOURCE
为gethostname()
包含原型.但是,指定-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
获得所需的行为.
读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_SOURCE
gcc -D_GNU_SOURCE -std=c99 file.c
_BSD_SOURCE
PS 手册页包含一个示例程序,可以打印当前的 ft 宏。您可以针对某些编译器设置编译并运行它。
归档时间: |
|
查看次数: |
7595 次 |
最近记录: |