簡體   English   中英

為什么sys / stat.h不使用-std = c1x定義ino_t?

[英]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_tblksize_tdev_tino_tmode_tnlink_tuid_tgid_toff_ttime_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.hino_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模式之間只有三個區別,而其中兩個通常不是您想要的:

  1. -std=cXX模式下,將禁用應用程序名稱空間中特定系統的預定義宏 這是一件好事; application-namespace預定義的宏充其量是令人困惑的,最壞的情況是破壞合法代碼。 但是,已知會破壞仍在尋找這些宏的系統頭文件。

  2. 三合在啟用-std=cXX模式和殘疾人-std=gnuXX模式。 你不想要三部曲; 它們在發明時就已經過時了,IMNSHO應該在很久以前就將它們從C標准中刪除。

  3. -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.

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