簡體   English   中英

Linux上的unistd.h和c99

[英]unistd.h and c99 on Linux

這個簡單的.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的優點嗎?

我看到其他標准庫存在同樣的問題。

您可能需要以特定方式定義一些宏以獲取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.hunistd.h隱式包含)將默認設置_BSD_SOURCE ,以便包含gethostname()的原型。 但是,指定-std=c99會導致編譯器自動定義__STRICT_ANSI__ ,這會導致features.h無法定義_BSD_SOURCE ,除非您使用自己的功能宏定義強制它(如上所述)。

gethostname( )不是標准的C函數(在C99標准中沒有提到它),因此在編譯到標准時正確地沒有定義符號。

如果您正在使用gcc工具鏈,請使用-std=gnu99 ,您將獲得所需的行為。

或者,查看<features.h> ,您似乎可以使用-D_GNU_SOURCE-D_XOPEN_SOURCE=500來獲得所需的行為。

閱讀man gethostname 它在功能測試宏要求中說,需要_BSD_SOURCE (或_XOPEN_SOURCE>500 )從unistd.h中提取gethostname。

接下來閱讀man feature_test_macros 你會發現-std=c99打開__STRICT_ANSI__ ,它關閉 _BSD_SOURCE 這意味着除非再次定義_BSD_SOURCE ,否則無法從unistd.h獲取gethostname 我通常在我的命令行上放置_GNU_SOURCE(即gcc -D_GNU_SOURCE -std=c99 file.c )以獲取大多數內容,這_BSD_SOURCE打開_BSD_SOURCE

PS手冊頁包含一個示例程序,可以打印當前的ft-macros。 您可以編譯並運行它以進行某些編譯器設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM