简体   繁体   English

Linux上的unistd.h和c99

[英]unistd.h and c99 on Linux

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. 结果.o文件很好,链接工作。 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. 我可以通过在我自己的.h文件中添加声明来以一种hacky方式实现这一点。

What is it about C99 that means the declarations in unistd.h don't get included? 什么是C99,这意味着unistd.h中的声明不包括在内? Can this be overcome, without giving up the niceness of C99? 这可以克服,而不放弃C99的优点吗?

I see the same problem for other standard libs. 我看到其他标准库存在同样的问题。

You may need to define some macros in a particluar way to get the prototype for gethostname() 您可能需要以特定方式定义一些宏以获取gethostname()的原型

From man gethostname : 来自man 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. 如果未指定-std-c99选项,则features.hunistd.h隐式包含)将默认设置_BSD_SOURCE ,以便包含gethostname()的原型。 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会导致编译器自动定义__STRICT_ANSI__ ,这会导致features.h无法定义_BSD_SOURCE ,除非您使用自己的功能宏定义强制它(如上所述)。

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. 或者,查看<features.h> ,您似乎可以使用-D_GNU_SOURCE-D_XOPEN_SOURCE=500来获得所需的行为。

Read man gethostname . 阅读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. 它在功能测试宏要求中说,需要_BSD_SOURCE (或_XOPEN_SOURCE>500 )从unistd.h中提取gethostname。

Next read man feature_test_macros . 接下来阅读man feature_test_macros You will find that -std=c99 turns on __STRICT_ANSI__ which in turns off _BSD_SOURCE . 你会发现-std=c99打开__STRICT_ANSI__ ,它关闭 _BSD_SOURCE This means you can't get gethostname from unistd.h unless you define _BSD_SOURCE again. 这意味着除非再次定义_BSD_SOURCE ,否则无法从unistd.h获取gethostname I usually place _GNU_SOURCE on my command line (ie gcc -D_GNU_SOURCE -std=c99 file.c ) for most things, which turns on _BSD_SOURCE as well. 我通常在我的命令行上放置_GNU_SOURCE(即gcc -D_GNU_SOURCE -std=c99 file.c )以获取大多数内容,这_BSD_SOURCE打开_BSD_SOURCE

PS The manual page contains an example program which can print the current ft-macros. PS手册页包含一个示例程序,可以打印当前的ft-macros。 You might compile and run it for some compiler settings. 您可以编译并运行它以进行某些编译器设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM