c99

1999年推出的C編程語言標準

C99(以前稱為C9X)是ISO/IEC9899:1999的非正式名稱,在1999年推出,被ANSI於2000年3月採用。它是C編程語言標準的過去版本。它擴展了以前的版本(C90),增加了語言和標準庫的新功能,並幫助實現更好地利用可用的計算機硬體,如IEEE754-1985浮點運算和編譯器技術,最主要的增強在數值處理上。2011年發布的C編程語言標準的C11版本取代了C99。

標準簡介


在ANSI的標準確立后,C語言的規範在一段時間內沒有大的變動,然而C++在自己的標準化創建過程中繼續發展壯大。《標準修正案一》在1994年為C語言創建了一個新標準,但是只修正了一些C89標準中的細節和增加更多更廣的國際字符集支持。不過,這個標準引出了1999年ISO9899:1999的發表。它通常被稱為C99。C99被ANSI於2000年3月採用。
但是各個公司對C99的支持所表現出來的興趣不同。當GCC和其它一些商業編譯器支持C99的大部分特性的時候,微軟Borland卻似乎對此不感興趣。
C99是在C89/90的基礎上發展起來的,增加了基本數據類型、關鍵字和一些系統函數等。
C99有一部分是對於增加了寬字符集,還加入了一些庫函數,是繼C89標準之後的第二個C語言官方標準。第一個C++語言官方標準C++98標準,就是基於C89編寫的,因此C99標準新增的語法特性在C++的編譯器中就或多或少地支持了,而完全或幾乎完全支持C99標準的主流編譯器有:GCC、Clang、IntelC++Compiler等。另外,VisualStudio2013也部分支持了C99語法特徵。
C99標準的草案是免費的。

新特性


在ANSI標準化發布了C89標準以後,C語言的標準在一段相當的時間內都保持不變,儘管C++繼續在改進。(實際上,NormativeAmendment1在1995年已經開發了一個新的C語言版本(即C95)。但是這個版本很少為人所知。)標準在90年代才經歷了改進,這就是ISO/IEC9899:1999(1999年出版)。這個版本就是通常提及的C99。
在C99中包括的特性有:
對編譯器限制增加了,比如源程序每行要求至少支持到4095位元組,變數名與函數名的要求支持到63位元組(extern要求支持到31)。
預編譯處理增強了。例如:
支持了可變參數的宏(VariadicMacro):#defineMacro(...)__VA_ARGS__
使用宏的時候,參數如果不寫,宏里用#,##這樣的東西會擴展成空串。(C89標準中會出錯的)
可變參數宏的示例代碼:
支持//行註釋(這個特性實際上在C89的很多編譯器上已經被支持了)
增加了新關鍵字restrict,inline,_Complex,_Imaginary,_Bool
支持longlong,longdouble_Complex,float_Complex這樣的類型
支持<::><%%>%:%:%:,等等奇怪的符號替代,D&E里提過這個
支持了不定長的數組。數組的長度就可以用變數了。聲明類型的時候呢,就用inta[*]這樣的寫法。不過考慮到效率和實現,這玩意並不是一個新類型。所以就不能用在全局裡,或者structunion裡面,如果你用了這樣的東西,goto語句就受限制了。
變數聲明不必放在語句塊的開頭,for語句提倡這麼寫for(inti=0;i<100;++i)就是說,inti的聲明放在裡面,i只在for裡面有效。(VC6.0沒有遵守這條標準,i在for外也有效;但vc2005里已經默認是i在外面不可見了,但有編譯選項可以設置。)
複合字面量:當一個類似結構的東西需要臨時構造的時候,可以用(type_name){xx,xx,xx}這有點像C++的構造函數
相較於C89標準,C99標準新增了一種結構體/數組的初始化方式,名叫designatedinitializers,即:
struct{inta[3],b;}w[]={[0].a={1},[1].a[0]=2};
字元串裡面,\u支持unicode的字元
支持16進位的浮點數的描述
所以printfscanf的格式化串增加了支持"%lld"和"%llu",對應longlongint類型和unsignedlonglongint類型(可以分別簡寫為longlong和unsignedlonglong)。
浮點數的內部數據描述支持了新標準,這個可以用#pragma編譯器指定
增加了一個內置的局部靜態字元數組變數__func__,可以用於得到當前函數的函數名。
對於非常量的表達式,也允許編譯器做化簡
修改了/%處理負數時的定義,這樣可以給出明確的結果,例如在C89中-22/7=-3,-22%7=-1,也可以-22/7=-4,-22%7=6。而C99中明確為-22/7=-3,-22%7=-1,只有一種結果。
取消了不寫函數返回類型默認就是int的規定
允許struct定義的最後一個數組寫做[]不指定其長度描述
constconstinti;將被當作constinti;處理
增加和修改了一些標準頭文件。比如定義bool,定義一些標準長度的int的,定義複數的定義寬字元的<wctype.h>有點泛型味道的數學函數跟浮點數有關的里多了一個va_copy可以複製...的參數。<time.h>里多了個structtmx對structtm做了擴展
輸入輸出對寬字元還有長整數等做了相應的支持
longdouble_Complex;longdouble_Imaginary。
頭文件中定義了complex和imaginary宏,並將它們擴展為_Complex和_Imaginary,因此在編寫新的應用程序時,應該使用頭文件中的complex和imaginary宏。下面是關於C99所支持的複數語法特性的使用示例代碼:
longlongint
C99標準中引進了longlongint(-2至2-1)和unsignedlonglongint(0到2-1)。longlongint能夠支持的整數長度為64位。
對數組的增強
可變長數組(VLA):C99中,程序員聲明數組時,數組的維數可以由任意有效的整型表達式確定,包括只在運行時才能確定其值的表達式,這類數組就叫做可變長數組。但是只有局部數組才可以是變長的。可變長數組的維數在數組生存期內是不變的,也就是說,可變長數組不是動態的。可以變化的只是數組的大小。可以使用*來定義不確定長的可變長數組。
c99單行註釋
字元//引入包含直到(但不包括)新換行符的所有多位元組字元的註釋,除非//字元出現在字元常量、字元串文字或註釋中。
c99分散代碼與聲明
C編譯器接受關於可執行代碼的混合類型聲明,如以下示例所示:
1
2
3
4
5
6
7
intmain(void)
intnuml=3;
printf("%d/n",num1);
intnum2=10;
printf("%d/n",num2);
return(0);
c99預處理程序的修改
(1)具有可變數目的參數的宏。C編譯器接受以下形式的#define預處理程序指令:
1
2
#defineidentifier(...)replacement_list
#defineidentifier(identifier_list,...)replacement_list
如果宏定義中的identifier__list以省略號結尾,則意味著調用中的參數比宏定義中的參數(不包括省略號)多;否則,宏定義中參數的數目(包括由預處理標記組成的參數)與調用中參數的數目匹配。對於在其參數中使用省略號表示法的#define預處理指令,在其替換列表中使用標識符__VA_ARGS__。
(2)_Pragma操作符。
Pragma(string-literal)形式的一元操作符表達式處理如下:
如果字元串文字具有L前綴,則刪除該前綴。
刪除前導和結尾雙引號。
雙引號替換每個換碼序列
用單個反斜杠替換每個換碼序列//。
(3)內部編譯指令。
STDCFP_CONTRACTON/OFF/DEFAULT
若為ON,浮點表達式被當做基於硬體方式處理的獨立單元,默認值是定義的工具。
STDCFEVNACCESSON/OFF/DEFAULT
告訴編譯程序可以訪問浮點環境,默認值是定義的工具。
STDCCX_LIMITED_RANGEON/OFF/DEFAULT
若值為ON,相當於告訴編譯程序某程序某些含有複數的公式是可靠的,默認是OFF。
(4)新增的內部宏。
__STDCHOSTED__若操作系統存在,則為1。
__STDC_VERSION__199991L或更高,代表C的版本。
__STDC_IEC_599__若支持IEC60559浮點運算,則為1。
__STDC_IEC_599_COMPLEX__若支持IEC60599複數運算,則為1。
__STDC_ISO_10646__由編譯程序支持,用於說明ISO/IEC10646標準的年和月。
格式:yyymmmL。
c99for語句內的變數聲明
C99中,程序員可以在for語句的初始化部分定義一個或多個變數,這些變數的作用域僅於本for語句所控制的循環體內。
C編譯器接受作為for循環語句中第一個表達式的類型聲明:
1for(inti=0;i<10;i++){//1oopbody};
for循環的初始化語句中聲明的任何變數的作用域是整個循環(包括控制和迭代表達式)。
c99複合賦值
C99中,複合賦值中,可以指定對象類型的數組、結構或聯合表達式,當使用複合賦值時,應在括弧內指定類型,後跟由花括弧圍起來的初始化列表;若類型為數組,則不能指定數組的大小,建成的對象是未命名的。
c99柔性數組結構成員
C99中,結構中的最後一個元素允許是未知大小的數組,這就叫做柔性數組成員,但結構中的柔性數組成員前面必須至少一個其他成員。柔性數組成員允許結構中包含一個大小可變的數組,sizeof返回的這種結構大小不包括柔性數組的內存,包含柔性數組成員的結構用malloc()函數進行內存的動態分配。並且分配的內存應該大於結構的大小,以適應柔性數組的預期大小。
c99複合賦值初始化符
C99中,該特性對經常使用稀疏數組的程序員十分有用,指定的初始化符通常有兩種用法:用於數組,以及用於結構體和共用體。
用於數組的格式:
1[index]=vol;
其中,index表示數組的下標,vol表示本數組元素的初始化值,例如:
1intx[10]={[0]=10,[5]=30};
其中只有x[0]和x[5]得到了初始化。這種方式不錯,但是VC6對他不支持。
用於結構體或共用體的格式如下:
member-name(成員名稱):對結構進行指定的初始化時,允許採用簡單的方法對結構中的指定成員進行初始化。
例如:
1structexample{intk,m,n;}object={m=10,n=200};
其中,沒有初始化k,對結構成員進行初始化的順序沒有限制。
c99printf()和scanf()函數系列的增強
C99中printf()和scanf()函數系列引進了處理longlongint和unsignedlonglongint數據類型的特性。longlongint類型的格式修飾符是II,在printf()和scanf()函數中,II適用於d.i.o.u和x格式說明符。
另外,C99還引進了hh修飾符,當使用d,i,o,u和x格式說明符時,hh用於指定char型參數,II和hh修飾符均可以用於n說明符。
格式修飾符a和A用在printf()函數中時,結果將會輸出十六進位的浮點數,格式如下:
[-]0xh,hhhhp+d
使用A格式修飾符時,x和p必須是大小,A和a格式修飾符也可以用在scanf()函數中,用於讀取浮點數,調用printf()函數時,允許在%f說明符前加上I修飾符,即%If,但不起作用。
c99C99新增的庫
C99新增的頭文件和庫:
支持複雜演演算法
給出對浮點狀態標記和浮點環境的其他方面的訪問
定義標準的、可移植的整型類型集合,也支持處理最大寬度整數的函數
用於定義對應各種運算符的宏
支持布爾數據類型,定義宏bool,以便兼容於C++
定義標準的、可移植的整型類型集合
定義一般類型的浮點宏
用於支持多位元組和寬位元組函數
用於支持多位元組和寬位元組分類函數
c99_func__預定義標識符
用於指出__func__所存放的函數名,類似於字元串賦值。
c99冪等限定符
類型限定符:如果同一限定符在同一說明符限定符列表中出現多次(無論直接出現還是通過一個或多個typedef),行為與該類型限定符僅出現一次時相同。
c99static及數組聲明符的限定符
關鍵字static可以出現在函數聲明符中參數的數組聲明符中,表示編譯器至少可以假定許多元素將傳遞到所聲明的函數中,使優化器能夠作出以其他方式無法確定的假定。
C編譯器將數組參數調整為指針,因此voidfoo(inta[])與voidfoo(int*a)相同。
如果您指定voidfoo(int*restricta);等類型限定符,則C編譯器使用實質上與聲明限定指針相同的數組語法voidfoo(inta[restrict]);表示它。
C編譯器還使用static限定符保留關於數組大小的信息。例如,如果指定voidfoo(inta[10]),則編譯器仍將它表達為voidfoo(int*a)。按以下所示使用static限定符:voidfoo(inta[static10]),讓編譯器知道指針a不是NULL,並且使用它可訪問至少包含十個元素的整數數組。

未來的工作


C11標準是ISO/IEC9899:2011-Informationtechnology--Programminglanguages--C的簡稱,曾用名為C1X
C11標準是C語言標準的第三版,前一個標準版本是C99標準。2011年12月8日,國際標準化組織(ISO)和國際電工委員會(IEC)旗下的C語言標準委員會(ISO/IECJTC1/SC22/WG14)正式發布了C11標準。
C11標準的最終定稿的草案是免費開放的,為N1570,但是正式標準文件需要198瑞士法郎
當前,支持此標準的主流C++語言編譯器有:GCC、Clang、IntelC++Compiler等。
c99相比C99的區別:
1.對齊處理操作符alignof,函數aligned_alloc(),以及頭文件
2._Noreturn函數標記,類似於gcc的__attribute__((noreturn))。例子:
1_Noreturnvoidthrd_exit(intres);
3._Generic關鍵詞,有點兒類似於gcc的typeof。示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
#defineGENERAL_ABS(x)_Generic((x),int:abs,float:fabsf,double:fabs)(x)
intmain(void)
{
printf("intabs:%d\n",GENERAL_ABS(-12));
printf("floatabs:%f\n",GENERAL_ABS(-12.04f));
printf("doubleabs:%f\n",GENERAL_ABS(-13.09876));
inta=10;
intb=0,c=0;
_Generic(a+0.1f,int:b,float:c,default:b)++;
printf("b=%d,c=%d\n",b,c);
_Generic(a+=1.1f,int:b,float:c,default:b)++;
printf("a=%d,b=%d,c=%d\n",a,b,c);
}
4.靜態斷言(staticassertions),_Static_assert(),在解釋#if和#error之後被處理。例子:
1_Static_assert(FOO>0,"FOOhasawrongvalue");
5.刪除了gets()函數,C99中已經將此函數被標記為過時,推薦新的替代函數gets_s()。
6.新的fopen()模式,(“…x”)。類似POSIX中的O_CREAT|O_EXCL,在文件鎖中比較常用。
7.匿名結構體/聯合體。
8.多線程支持,包括:_Thread_local,頭文件,裡面包含線程的創建和管理函數(比如thrd_create(),thrd_exit()),mutex(比如mtx_lock(),mtx_unlock())等等。
9._Atomic類型修飾符和頭文件
10.帶邊界檢查(Bounds-checking)的函數介面,定義了新的安全的函數,例如fopen_s(),strcat_s()等等。
11.改進的Unicode支持,新的頭文件等。實例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include
#include
size_tUTF16StrLen(constchar16_t*utf16String)
{
if(utf16String==NULL)
return0;
size_tindex;
for(index=0;utf16String[index]!=u'\0';index++);
returnindex;
}
size_tUTF16ToUTF8(char*mbBuffer,constchar16_t*utf16String)
{
if(mbBuffer==NULL||utf16String==NULL)
return0;
mbstate_tstate={};
size_tmbIndex=0;
for(intutf16Index=0;utf16String[utf16Index]!=u'\0';utf16Index++)
{
constsize_tlength=c16rtomb(&mbBuffer[mbIndex],utf16String[utf16Index],&state);
mbIndex+=length;
}
mbBuffer[mbIndex]='\0';
returnmbIndex;
}
intmain(intargc,char*argv[])
{
char16_tch=u'好';
charchBuffer[64];
mbstate_tstate={};
size_tlength=c16rtomb(chBuffer,ch,&state);
chBuffer[length]='\0';
printf("TheUTF-8characterlengthis:%zu,andthecharacteris:%s\n",length,chBuffer);
constchar*utf8Str=u8"你好,世界。";
printf("TheUTF-8stringis:%s\n",utf8Str);
constchar16_t*utf16Str=u"你好,世界。";
printf("Theutf16stringlengthis:%zu\n",UTF16StrLen(utf16Str));
length=UTF16ToUTF8(chBuffer,utf16Str);
printf("TheUTF-8stringlengthis:%zu,andthecontentis:%s\n",length,chBuffer);
printf("IftheconvertedUTF-8stringisequaltotheoriginalone?%s\n",strcmp(chBuffer,utf8Str)==0?"YES":"NO");
}
12.新增quick_exit()函數,作為第三種終止程序的方式,當exit()失敗時可以做最少的清理工作(deinitializition)。
13.創建複數的宏,CMPLX()。
14.更多浮點數處理的宏(Moremacrosforqueryingthecharacteristicsoffloatingpointtypes,concerningsubnormalfloatingpointnumbersandthenumberofdecimaldigitsthetypeisabletostore)。
15.structtimespec成為time.h的一部分,以及宏TIME_UTC,函數timespec_get()。

歷史


ANSI於1989年制定了C編程語言的官方標準,並於1990年成為國際標準,C語言規範在一段時間內保持相對靜態,而C++繼續發展,主要是在其自身的標準化工作中。規範修正案1在1995年為C制定了一個新標準,但只是為了糾正1989年標準的一些細節,並為國際字符集增加了更廣泛的支持。該標準在20世紀90年代後期進行了進一步修訂,導致1999年出版了ISO/IEC9899:1999,並於2000年5月作為ANSI標準採用。該標準版本定義的語言通常稱為“C99"。國際C標準由ISO/IECJTC1/SC22/WG14工作組維護。

設計


在大多數情況下,C99與C89向後兼容,但在某些方面它更嚴格。
特別是,缺少類型說明符的聲明不再隱含假定的int。C標準委員會認為,編譯器診斷無意中遺漏類型說明符比靜默處理依賴於隱式int遺留代碼更有價值。在實踐中,編譯器可能會顯示警告,然後假設為int並繼續翻譯程序。
C99引入了幾個新功能,其中許多已經在幾個編譯器中作為擴展實現:
混合聲明和代碼:變數聲明不再局限於文件範圍或複合語句(塊)的開頭,便於靜態單一賦值形式
幾種新的數據類型,包括longlongint,可選的擴展整數類型,顯式布爾數據類型和表示複數的complex類型
可變長度數組(雖然隨後在C11中降級為條件特徵,不需要支持實現)
靈活的陣列成員
支持以//開頭的單行註釋,如BCPL,C++和Java
新的庫函數,例如snprintf
新標頭,例如
type-generic數學(宏)函數,在,它根據float,double或longdouble參數等選擇數學庫函數。
改進了對IEEE浮點的支持
指定的初始化者
複合文字(例如,可以在函數調用中構造結構:function((structx){1,2}))
支持可變參數宏(具有可變數量參數的宏)
restrict允許更積極的代碼優化,消除FORTRAN以前在ANSIC保留的編譯時數組訪問優勢
通用字元名稱,允許用戶變數包含除標準字符集之外的其他字元
參數聲明中數組索引中的關鍵字static
C99標準的某些部分包含在當前版本的C++標準中,包括整數類型,標題和庫函數。可變長度數組不屬於這些包含的部分,因為C++的標準模板庫已經包含類似的功能。

關鍵字


c99數據類型關鍵字
1、char[tɑ:]:聲明字元型變數或函數
2、double[dbl]:聲明雙精度變數或函數
3、enum:聲明枚舉類型
4、float[flut]:聲明浮點型變數或函數
5、int[int]:聲明整型變數或函數
6、long[l]:聲明長整型變數或函數
7、short[:t]:聲明短整型變數或函數
8、signed:聲明有符號類型變數或函數
9、struct:聲明結構體變數或函數
10、union[ju:nin]:聲明共用體(聯合)數據類型
11、unsigned[n'saind]:聲明無符號類型變數或函數
12、void[vid]:聲明函數無返回值或無參數,聲明無類型指針
c99控制語句關鍵字
A循環語句
1、for[f,f:]:一種循環語句
2、do[du,du:]:循環語句的循環體
3、while[wail]:循環語句的循環條件
4、break[breik]:跳出當前循環
5、continue[kntinju:]:結束當前循環,開始下一輪循環
B條件語句
1、if[if]:條件語句
2、else[els]:條件語句否定分支(與if連用)
3、goto:無條件跳轉語句
C開關語句
1、switch[swit]:用於開關語句
2、case[keis]:開關語句分支
3、default[dif:lt]:開關語句中的“其他”分支
D返回語句
1、return[rit:n]:子程序返回語句
c99存儲類型關鍵字
1、auto[:tu]:聲明自動變數
2、extern:聲明變數是在其他文件正聲明
3、register[redist]:聲明積存器變數
4、static[sttik]:聲明靜態變數
c99其它關鍵字
1、const:聲明只讀變數
2、sizeof:計算數據類型長度
3、typedef:用以給數據類型取別名
4、volatile[vltail]:說明變數在程序執行中可被隱含地改變
c99C99新增
1、inline關鍵字用來定義一個類的內聯函數,引入它的主要原因是用它替代C中表達式形式的宏定義
引入原因:C語言是一個效率很高的語言,這種宏定義在形式及使用上像一個函數,但它使用預處理器實現,沒有了參數壓棧,代碼生成等一系列的操作
2、restrict關鍵字只用於限定指針;該關鍵字用於告知編譯器,所有修改該指針所指向內容的操作全部都是基於(baseon)該指針的,即不存在其它進行修改操作的途徑;這樣的後果是幫助編譯器進行更好的代碼優化,生成更有效率的彙編代碼。
3、_Bool關鍵字是用於表示布爾值。包含標準頭文件stdbool.h后,我們可以用bool代替_Bool,true代替1,false代替0。
4、_Complexand_Imaginary關鍵字
C99標準中定義的複數類型如下:float_Complex;float_Imaginary;double_Complex;double_Imaginary;longdouble_Complex;longdouble_Imaginary.
頭文件中定義了complex和imaginary宏,並將它們擴展為_Complex和_Imaginary,因此在編寫新的應用程序時,應該使用頭文件中的complex和imaginary宏。

版本檢測


標準宏__STDC_VERSION__定義為值199901L,表示C99支持可用。與C90的__STDC__宏一樣,__STDC_VERSION__可用於編寫將針對C90和C99編譯器進行不同編譯的代碼,如此示例中確保在任何一種情況下都可以使用inline(通過在C90中將其替換為static以避免鏈接器錯誤))。
?
1
2
#if__STDC_VERSION__>=199901L
 

實施


大多數C編譯器至少支持C99中引入的一些功能。
從歷史上看,Microsoft在其VisualC++工具中實現新C功能的速度很慢,而主要側重於支持C++標準的開發。然而,隨著VisualC++2013的引入,Microsoft實現了C99的有限子集,它在VisualC++2015中進行了擴展。
編譯器支持程度C99兼容性細節
橡子C/C++局部官方文檔指出支持“大多數”編譯器功能,以及庫函數的“一些”。
AMDx86Open64編譯器套件大多C99的支持是否與GCC相同。
cc65局部未實現完整的C89和C99支持,部分原因是平台限制(MOS技術6502)。某些C99類型沒有計劃支持,如_Complex和64位整數(longlong)。
局部支持主要的C99功能。
大多支持除C99浮點pragma之外的所有功能。
CompCert大多經過認證的編譯器,正式證明是正確的。支持除C99複數和VLA之外的所有功能,以及對switch語句的小限制(沒有Duff的設備)。
cparser充分支持C99功能。
C++Builder僅在64位模式下,因為後者是CLangfork
數字火星C/C++編譯器局部缺少對某些功能的支持,例如和_Pragma。
GCC大多截至2014年6月,主線GCC中缺少擴展標識符,標準編譯指示和IEEE754/IEC60559浮點支持。此外,某些功能(例如擴展整數類型和新庫函數)必須由C標準庫提供,並且不在GCC範圍內。GCC的4.6和4.7版本也提供相同級別的合規性。部分IEEE754支持,即使硬體是兼容的:可能需要一些編譯器選項來避免不正確的優化(例如,-std=c99和-fsignaling-nans),但完全支持定向舍入模式是即使使用-frounding-math也會丟失。
青山軟體充分
IBMCforAIX,V6和XLC/C++V11.1forAIX充分
IBMRationallogiscope充分在Logiscope6.3之前,只支持C99的基本結構。Logiscope6.4及更高版本正式支持C99。
波特蘭集團PGIC/C++充分
IAR系統 嵌入式工作台大多不支持UCN(通用字元名稱)。用於嵌入式目標的編譯器,例如ARMColdfire,MSP430,AVRAVR32,8051,......Nox86目標。
英特爾C++編譯器大多
MicrosoftVisualC++部分VisualC++2012及更早版本不支持C99。 VisualC++2013實現了編譯流行的開源項目所需的有限C99子集。 VisualC++2015實現了C99標準庫,但依賴於編譯器尚未支持的編譯器功能的任何庫功能除外(例如,未實現)。
打開Watcom局部實現標準中最常用的部分。但是,它們僅通過未記錄的命令行開關“-za99”啟用。自從v1.0之前的C90擴展以來,已經捆綁了三個C99功能:C++樣式註釋(//),靈活的數組成員,枚舉聲明中允許的尾隨逗號。
PellesC.充分支持所有C99功能。
攜帶型C編譯器局部致力於符合C99標準。
太陽工作室滿
阿姆斯特丹編譯器套件C99前端目前正在調查中。
微小的C編譯器局部不支持複數。支持可變長度數組,但不支持函數。開發人員表示“TCC正朝著完全符合ISOC99的方向發展”。
VBCC局部