unistd。h和c99在Linux上

时间:2023-01-07 09:36:44

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的示例程序。您可以为某些编译器设置编译并运行它。