[英]Why won't sys/stat.h define ino_t with -std=c1x?
我正在編寫的一些C代碼遇到一個奇怪的問題。 考慮以下代碼:
#include <sys/stat.h>
ino_t inode;
根據POSIX.1-2008 ,頭文件<sys / stat.h >定義了ino_t
1 :
<sys / stat.h>標頭應定義
blkcnt_t
,blksize_t
,dev_t
,ino_t
,mode_t
,nlink_t
,uid_t
,gid_t
,off_t
和time_t
類型,如<sys / types.h>中所述 。
當我嘗試在Linux系統上的文件test.c中編譯以上源代碼時,會發生這種情況:
$ cat test.c #include <sys/stat.h> ino_t inode; $ uname -srm Linux 3.8.0-26-generic x86_64 $ lsb_release -d Description: Ubuntu 13.04 $ gcc -c test.c $ gcc -std=c90 test.c test.c:2:1: error: unknown type name 'ino_t' $ gcc -std=c99 test.c test.c:2:1: error: unknown type name 'ino_t' $ gcc -std=c1x test.c test.c:2:1: error: unknown type name 'ino_t'
為什么在指定任何-std選項時ino_t
的定義ino_t
?
我的fstat
手冊頁上說還包括sys/types.h
,這為我解決了問題。 sys/stat.h
中ino_t
的定義受功能宏__USE_XOPEN
和__USE_XOPEN2K
。 sys/types.h
的定義不受這種保護。
手冊頁還說包含unistd.h
,但這對於解決您的問題不是必需的。
根據feature_test_macros
的手冊頁:
__STRICT_ANSI__
ISO標准C。使用例如-std=c99
或-ansi
標志調用時,此宏由gcc(1)隱式定義。
我想這意味着所有XOPEN功能也都被關閉了。 但是,我找不到任何描述。
PS似乎R ..(見下文)感覺在feature_test_macros
的手冊頁中也有介紹,但是我有限的大腦無法找到確切的用詞,因此我想把它留給讀者練習。 如果在任何地方對其進行了描述,那么我確實希望在該手冊頁中可以找到它。
注意此答案的要點如下:
您應包括手冊頁中提到的所有包含文件,而不要對可能不需要的文件進行反向工程。
如果使用-std=gnuXX
而不是-std=cXX
則程序可以毫無抱怨地進行編譯。
$ cc -std=c11 -fsyntax-only test.c ; echo $?
test.c:2:1: error: unknown type name ‘ino_t’; did you mean ‘__ino_t’?
1
但
$ cc -std=gnu11 -fsyntax-only test.c ; echo $?
0
許多人對-std=cXX
選項的效果-std=cXX
。 他們自己並沒有告訴GCC嚴格遵守(例如,診斷所有使用GNU擴展的信息)。 如果要嚴格遵守,還必須提供-Wall -Wpedantic
選項。
-std=cXX
模式和對應的-std=gnuXX
模式之間只有三個區別,而其中兩個通常不是您想要的:
在-std=cXX
模式下,將禁用應用程序名稱空間中特定於系統的預定義宏 。 這是一件好事; application-namespace預定義的宏充其量是令人困惑的,最壞的情況是破壞合法代碼。 但是,已知會破壞仍在尋找這些宏的系統頭文件。
三合在啟用-std=cXX
模式和殘疾人-std=gnuXX
模式。 你不想要三部曲; 它們在發明時就已經過時了,IMNSHO應該在很久以前就將它們從C標准中刪除。
在-std=cXX
模式下,GNU libc將嘗試最小化在其標頭中可見的超出指定C標准的擴展數量。 (警告:可以與GCC一起使用的許多其他C庫都不會這樣做。)對於sys/stat.h
類的標頭不屬於C標准的情況,它的意思是“僅公開功能“我們支持的此標頭的最舊版本中包含的內容”,這通常非常古老且受限制,例如POSIX.1-1993。 這就是讓您絆倒的原因。 您可以通過定義功能測試宏來解決該問題,以指示GNU libc公開較新的POSIX等功能。
如果您是從頭開始編寫新的C程序,我建議您使用-Wall
和-Wpedantic
(可能還有許多其他-W
開關 ),但我不建議使用-std=cXX
,因為唯一的積極效果是關閉系統特定的預定義,這可能會破壞系統頭。 這也是幾乎總是少些麻煩直來直去的_GNU_SOURCE
或相當於比futz周圍試圖找到一個_POSIX_C_SOURCE
或_XOPEN_SOURCE
設置,為您提供所需的一切(特別是如果你或你捆綁第三方代碼,可能使用deprecated-但仍然很常見的功能,例如gettimeofday
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.