代码之家  ›  专栏  ›  技术社区  ›  slim

Linux上的unistd.h和c99

  •  11
  • slim  · 技术社区  · 14 年前

    这个简单的.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文件中,以一种黑客的方式实现这一点。

    c99的意思是unistd.h中的声明不包括在内? 在不放弃C99的优良性的情况下,能否克服这一点?

    我认为其他标准libs也存在同样的问题。

    3 回复  |  直到 14 年前
        1
  •  16
  •   Michael Burr    14 年前

    您可能需要用particlurar的方式定义一些宏来获取 gethostname()

    man gethostname :

    功能测试宏要求 glibc(见功能测试宏(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__ 从而导致 特点 不定义 γBSD源 ,除非您使用自己的功能宏定义(如上所述)强制它。

        2
  •  10
  •   Stephen Canon    14 年前

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

    如果您使用 gcc 工具链,使用 -std=gnu99 你会得到你想要的行为。

    或者,看看 <features.h> 好像你可以用 -D_GNU_SOURCE -D_XOPEN_SOURCE=500 以获得所需的行为。

        3
  •  4
  •   Nordic Mainframe    14 年前

    man gethostname . 它在特性测试宏需求中说, _BSD_SOURCE (或) _XOPEN_SOURCE>500 )需要从unistd.h中提取gethostname。

    下一读 man feature_test_macros . 你会发现的 -std=c99 打开 __STRICT_ANSI__ 其中 关掉 γBSD源 . 这意味着你不能 gethostname unistd.h 除非你定义 γBSD源 再一次。我通常在命令行(即 gcc -D_GNU_SOURCE -std=c99 file.c )在大多数情况下,它会打开 γBSD源 也。

    另外,手册页包含一个示例程序,可以打印当前的FT宏。您可以为一些编译器设置编译并运行它。