2014-10-22 94 views
12

我正在嘗試在測試嚴格的 C90一致性時使用gcc標誌的組合。根據之前的帖子:GCC options for strictest C code?,我應該只需要一個--std = c90。嚴格C90代碼的GCC選項?

但這裏是我的嘗試:

$ cat t.c 
#include <stdint.h> /* added in C99 */ 

int main() 
{ 
    uint64_t t; 
    return 0; 
} 
$ gcc -std=c90 -ansi -pedantic t.c 

上述不正常工作(沒有警告/錯誤的產生)。

請問的人知道:

  1. GCC標誌有嚴格的ISO/IEC 9899:1990的一致性
  2. 不同的編譯器(TCC,鐺......)與不同組標誌?

編輯:

對不起,我的措辭,是的,我真的想模仿嚴格符合C90編譯器,換句話說,如果代碼嘗試使用後新增任何功能應該失敗(C99來心神)。因此pthread包含標頭應該編譯時會發出警告GNU/GCC calls C90 mode(就像stdint.h頭文件應該產生一個沒有C99的警告)。 -pedantic很好地警告我使用long long,我不明白爲什麼它不應該警告我關於uint64_t

我用的ISO/IEC 9899的術語:

在1990年,ANSI C標準(帶格式的變化)是由 通過:1990從引國際標準化組織(ISO)作爲ISO/IEC 9899:1990,其有時被稱爲C90。因此,術語「C89」 和「C90」是指相同的編程語言。

EDIT2:

GCC文件實際上是相當清楚的:

某些功能是被接納爲C90模式 擴展C99標準的一部分,有些功能是一部分C9 標準被接受爲C90和C99模式下的擴展。

所以我的問題是改寫成:

  • 是否有一個編譯器+標準包括一個Linux系統,它嚴格遵循C90的頭?
+1

請注意,C90是在標準ISO/IEC 9899中指定的。您要求符合ISO/IEC 9945-1這是POSIX標準。 – Lundin 2014-10-22 07:41:44

+0

我還沒有聽說過一個編譯器,可以讓你檢查這個。一些編譯器,例如gcc和clang以及一個3. party標準庫一起使用時間很長,以支持所要求的標準,尤其是在語言級別,但它們並不意味着要成爲合規性檢查器。對於庫特性,它更加不實際,因爲C允許使用非標準庫/頭文件,所以沒有什麼能阻止執行文件將stdint.h提供到C89編譯器 - 例如gcc和clang不提供庫/頭文件 - 這留給了3方(通常是linux上的glibc) – nos 2014-10-22 08:10:42

+1

你說*應該*發出警告,你的證明在哪裏?在梳理完標準後,我沒有看到它說需要編譯器發佈診斷的地方。 – 2014-10-22 08:10:50

回答

1

請記住,GCC本身是符合規定的獨立式的執行C標準;這樣的實現只提供標準頭文件的一小部分,實際上沒有C標準庫的實際功能,而是依賴於另一方 - 例如在Linux系統上 - 提供C標準庫的功能。

你追求的是什麼東西,不是隻有當你使用的是C99警告你/ C11/GNU 語言功能,是不是在C90,但是當你使用功能未被C90本身定義。可悲的是,僅僅因爲上述原因,編譯器無法做到這一點 - 它與libc一起使用時很難。上glibc系統,C標準庫將拿起由-std=c90-ansi定義的宏:

__STRICT_ANSI__使用-ansi選項時被預定義。某些頭文件可能會注意到這個宏,並且避免聲明某些函數或者定義ISO標準不要求的某些宏;這是爲了避免干擾任何可能將這些名稱用於其他事情的程序。

,並給你通過關閉無償擴展一些幫助:如果您在使用‘gcc -ansi’編譯程序

,你只得到了ISO C庫功能,除非你明確要求額外的功能通過定義一個或更多的功能宏。

但是,這隻包括擴展和POSIX-but-not-ISO C函數;如果函數的行爲在ISO C和POSIX.1中有不同的規定,它將不會保存你!

12

C90合規性並不意味着編譯器不能提供其他在C90標準中未提及的標頭。 (例如,sys/socket.h。)如果由於一些奇怪的原因而想禁止這些選項,可以通過-I選項來添加一個額外的包含路徑,並在該路徑中放入所有僅限於C99的標題的版本,這些標題僅爲#error Don't include me

+2

「出於某種奇怪的原因」 - 原因並不奇怪。如果OP想要測試他們的代碼以確保它沒有任何特定於C99或OS的依賴關係,那麼他們肯定不希望限制自己使用這些標頭。 – 2014-10-22 07:42:04

+0

編譯器也可以解析給定的頭文件,如果有的話解析宏,而不包含任何內容,因爲在展開宏和計算條件之後,頭文件不會生成任何文本/代碼作爲選項傳遞給編譯器的結果。畢竟,使用'#ifdef'或'ifndef'或其他選項來保護你的頭文件免受不必要的包含是不難的。 – user2485710 2014-10-22 08:15:15

+0

@TheParamagneticCroissant我不知道任何編譯器/運行時間,專門存在的目的是不允許C99構造。這將是一個完全無法回報的編譯器。即使在GCC提供的C90頭文件中,我也確定存在不屬於C90標準的函數定義。 – Sneftel 2014-10-23 21:46:37