【问题标题】:unistd.h and c99 on LinuxLinux 上的 unistd.h 和 c99
【发布时间】:2010-07-28 16:51:26
【问题描述】:

这个简单的 .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 的优点的情况下克服这一点?

我发现其他标准库也存在同样的问题。

【问题讨论】:

    标签: c linux unix c99


    【解决方案1】:

    您可能需要以特定方式定义一些宏来获取gethostname() 的原型

    来自man gethostname

    功能测试宏要求 glibc(参见 feature_test_macros(7)):

       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);
    }
    

    血淋淋的细节:

    如果您不指定-std-c99 选项,那么features.h(由unistd.h 隐含包含)将默认设置_BSD_SOURCE,从而包含gethostname() 的原型。但是,指定-std=c99 会导致编译器自动定义__STRICT_ANSI__,这反过来又会导致features.h 不定义_BSD_SOURCE,除非您使用自己的功能宏定义(如上)强制它。

    【讨论】:

    • +1 以获得答案。 -10 代表#define _BSD_SOURCE。请在构建链中使用#define _XOPEN_SOURCE 500 或更好:cc -D_XOPEN_SOURCE=500 ...。好吧,如果需要任何类型的可移植性。
    • 正如我对 Luther 的回复——我的 Red Hat 系统上的 man gethostname 没有提及功能测试宏要求。有人知道为什么吗?
    【解决方案2】:

    gethostname( ) 不是标准的 C 函数(在 C99 标准中的任何地方都没有提及),因此编译到标准时没有正确定义符号。

    如果您使用gcc 工具链,请使用-std=gnu99,您将获得所需的行为。

    或者,查看&lt;features.h&gt;,您似乎可以使用-D_GNU_SOURCE-D_XOPEN_SOURCE=500 来获得所需的行为。

    【讨论】:

    • 虽然我接受了不同的答案,但-std=gnu99 是我实际使用的修复程序。谢谢。
    • 刚好遇到这个问题,也选择-std=gnu99
    【解决方案3】:

    阅读man gethostname。它在功能测试宏要求中说,需要_BSD_SOURCE(或_XOPEN_SOURCE&gt;500)从 unistd.h 中提取 gethostname。

    接下来阅读man feature_test_macros。你会发现-std=c99 开启了__STRICT_ANSI__,在关闭 _BSD_SOURCE。这意味着你不能从unistd.h 得到gethostname,除非你再次定义_BSD_SOURCE。对于大多数事情,我通常将 _GNU_SOURCE 放在我的命令行(即gcc -D_GNU_SOURCE -std=c99 file.c)上,这也会打开_BSD_SOURCE

    附:手册页包含一个可以打印当前 ft-macros 的示例程序。您可以针对某些编译器设置编译并运行它。

    【讨论】:

    • 我的 redhat 系统上的 man gethostname 中没有这些。你的是什么系统?我应该安装额外的联机帮助页吗?
    猜你喜欢
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多