This simple .c file:
这个简单的c文件:
#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:
…但在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'
$
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.
生成的.o文件很好,可以链接。我只是想摆脱这个警告。通过在我自己的.h文件中放入声明,我可以以一种简单的方式实现这一点。
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?
关于C99的什么意思是unistd的声明。包括h不走?如果不放弃C99的美好,这能被克服吗?
I see the same problem for other standard libs.
对于其他标准的lib,我也看到了同样的问题。
3 个解决方案
#1
15
You may need to define some macros in a particluar way to get the prototype for gethostname()
您可能需要以一种分区方式定义一些宏来获得gethostname()的原型
From man gethostname
:
从男人gethostname:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
glibc的特性测试宏需求(参见feature_test_macros(7)):
gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
So:
所以:
#define _BSD_SOURCE
#include <unistd.h>
void test() {
char string[40];
gethostname(string,40);
}
The gory details:
细节:
If you don't specify the -std-c99
option, then features.h
(which is implicitly included by unistd.h
) will default to setting _BSD_SOURCE
in such a way that the prototype for gethostname()
gets included. However, specifying -std=c99
causes the compiler to automatically define __STRICT_ANSI__
, which in turn causes features.h
to not define _BSD_SOURCE
, unless you force it with your own feature macro definition (as above).
如果不指定-std-c99选项,那么就指定特性。h (unistd.h隐式包含)将默认设置_BSD_SOURCE,以便包含gethostname()的原型。但是,指定-std=c99会导致编译器自动定义__STRICT_ANSI__,这反过来又会产生特性。h不定义_BSD_SOURCE,除非您强制使用自己的特性宏定义(如上所示)。
#2
10
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.
gethostname()不是一个标准的C函数(在C99标准中没有提到),因此在编译到标准时没有正确地定义符号。
If you're using the gcc
toolchain, use -std=gnu99
and you'll get the behavior you want.
如果您正在使用gcc工具链,那么使用-std=gnu99,您将得到您想要的行为。
Alternatively, looking at <features.h>
, it seems like you could use -D_GNU_SOURCE
or -D_XOPEN_SOURCE=500
to get the desired behavior.
另外,看 <特性。h> ,似乎可以使用-D_GNU_SOURCE或-D_XOPEN_SOURCE=500来获得所需的行为。
#3
4
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.
读gethostname人。它在特性测试宏需求中说,需要_BSD_SOURCE(或_XOPEN_SOURCE>500)从unistd.h中提取gethostname。
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 get gethostname
from unistd.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.
下一个feature_test_macros读人。您将发现-std=c99打开__STRICT_ANSI__,它关闭_BSD_SOURCE。这意味着你不能从unistd获得gethostname。除非再次定义_BSD_SOURCE。我通常将_GNU_SOURCE放在命令行上(即gcc -D_GNU_SOURCE -std=c99 file.c),这也会打开_BSD_SOURCE。
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.
手册页包含一个可以打印当前ft-macros的示例程序。您可以为某些编译器设置编译并运行它。
#1
15
You may need to define some macros in a particluar way to get the prototype for gethostname()
您可能需要以一种分区方式定义一些宏来获得gethostname()的原型
From man gethostname
:
从男人gethostname:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
glibc的特性测试宏需求(参见feature_test_macros(7)):
gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
So:
所以:
#define _BSD_SOURCE
#include <unistd.h>
void test() {
char string[40];
gethostname(string,40);
}
The gory details:
细节:
If you don't specify the -std-c99
option, then features.h
(which is implicitly included by unistd.h
) will default to setting _BSD_SOURCE
in such a way that the prototype for gethostname()
gets included. However, specifying -std=c99
causes the compiler to automatically define __STRICT_ANSI__
, which in turn causes features.h
to not define _BSD_SOURCE
, unless you force it with your own feature macro definition (as above).
如果不指定-std-c99选项,那么就指定特性。h (unistd.h隐式包含)将默认设置_BSD_SOURCE,以便包含gethostname()的原型。但是,指定-std=c99会导致编译器自动定义__STRICT_ANSI__,这反过来又会产生特性。h不定义_BSD_SOURCE,除非您强制使用自己的特性宏定义(如上所示)。
#2
10
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.
gethostname()不是一个标准的C函数(在C99标准中没有提到),因此在编译到标准时没有正确地定义符号。
If you're using the gcc
toolchain, use -std=gnu99
and you'll get the behavior you want.
如果您正在使用gcc工具链,那么使用-std=gnu99,您将得到您想要的行为。
Alternatively, looking at <features.h>
, it seems like you could use -D_GNU_SOURCE
or -D_XOPEN_SOURCE=500
to get the desired behavior.
另外,看 <特性。h> ,似乎可以使用-D_GNU_SOURCE或-D_XOPEN_SOURCE=500来获得所需的行为。
#3
4
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.
读gethostname人。它在特性测试宏需求中说,需要_BSD_SOURCE(或_XOPEN_SOURCE>500)从unistd.h中提取gethostname。
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 get gethostname
from unistd.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.
下一个feature_test_macros读人。您将发现-std=c99打开__STRICT_ANSI__,它关闭_BSD_SOURCE。这意味着你不能从unistd获得gethostname。除非再次定义_BSD_SOURCE。我通常将_GNU_SOURCE放在命令行上(即gcc -D_GNU_SOURCE -std=c99 file.c),这也会打开_BSD_SOURCE。
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.
手册页包含一个可以打印当前ft-macros的示例程序。您可以为某些编译器设置编译并运行它。