Linux 上的 unistd.h 和 c99
这个简单的 .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 优点的情况下克服这个问题吗?
我发现其他标准库也存在同样的问题。
This simple .c file:
#include <unistd.h>
void test() {
char string[40];
gethostname(string,40);
}
... when compiled normally, works fine:
$ cc -Wall -c -o tmp.o tmp.c
$
... but when compiled in C99 mode, gives a warning:
$ cc -Wall -std=c99 -c -o tmp.o tmp.c
tmp.c: In function `test':
tmp.c:5: warning: implicit declaration of function `gethostname'
$
The resultant .o file is fine, and linking works. I'd just like to get rid of the warning. I can achieve this in a hacky way, by putting declarations in my own .h file.
What is it about C99 that means the declarations in unistd.h don't get included?
Can this be overcome, without giving up the niceness of C99?
I see the same problem for other standard libs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
获取
gethostname()
的原型您可能需要以特定方式定义一些宏,以从
man gethostname
所以:
血淋淋的细节:
如果您没有指定
-std-c99
选项,则features.h
(这是隐式的由unistd.h
包含)将默认设置_BSD_SOURCE
,以便包含gethostname()
的原型。但是,指定-std=c99
会导致编译器自动定义__STRICT_ANSI__
,进而导致features.h
不定义_BSD_SOURCE
,除非您使用自己的功能宏定义强制它(如上所述)。You may need to define some macros in a particluar way to get the prototype for
gethostname()
From
man gethostname
:So:
The gory details:
If you don't specify the
-std-c99
option, thenfeatures.h
(which is implicitly included byunistd.h
) will default to setting_BSD_SOURCE
in such a way that the prototype forgethostname()
gets included. However, specifying-std=c99
causes the compiler to automatically define__STRICT_ANSI__
, which in turn causesfeatures.h
to not define_BSD_SOURCE
, unless you force it with your own feature macro definition (as above).gethostname( )
不是标准 C 函数(C99 标准中没有提及),因此在编译到标准时未正确定义该符号。如果您使用的是
gcc
工具链,请使用-std=gnu99
,您将获得您想要的行为。或者,查看
,似乎您可以使用-D_GNU_SOURCE
或-D_XOPEN_SOURCE=500
来获得所需的行为。gethostname( )
is not a standard C function (it's not mentioned anywhere in the C99 standard), so the symbol is correctly not defined when compiling to the standard.If you're using the
gcc
toolchain, use-std=gnu99
and you'll get the behavior you want.Alternatively, looking at
<features.h>
, it seems like you could use-D_GNU_SOURCE
or-D_XOPEN_SOURCE=500
to get the desired behavior.阅读
man gethostname
。在功能测试宏要求中,需要_BSD_SOURCE
(或_XOPEN_SOURCE>500
)从 unistd.h 中提取 gethostname。接下来阅读
man feature_test_macros
。您会发现-std=c99
打开__STRICT_ANSI__
,__STRICT_ANSI__
关闭_BSD_SOURCE
。这意味着您无法从unistd.h
获取gethostname
,除非您再次定义_BSD_SOURCE
。对于大多数情况,我通常将 _GNU_SOURCE 放在命令行上(即gcc -D_GNU_SOURCE -std=c99 file.c
),这也会打开_BSD_SOURCE
。PS 手册页包含一个示例程序,可以打印当前的 ft 宏。您可以针对某些编译器设置编译并运行它。
Read
man gethostname
. It says in the Feature Test Macro Requirements, that_BSD_SOURCE
(or_XOPEN_SOURCE>500
) is required to pull gethostname from unistd.h.Next read
man feature_test_macros
. You will find that-std=c99
turns on__STRICT_ANSI__
which in turns off_BSD_SOURCE
. This means you can't getgethostname
fromunistd.h
unless you define_BSD_SOURCE
again. I usually place _GNU_SOURCE on my command line (i.e.gcc -D_GNU_SOURCE -std=c99 file.c
) for most things, which turns on_BSD_SOURCE
as well.P.S. The manual page contains an example program which can print the current ft-macros. You might compile and run it for some compiler settings.