-
C11
鎖定
C11標準是 ISO/IEC 9899:2011 - Information technology -- Programming languages -- C 的簡稱
[1]
,曾用名為C1X。
- 中文名
- C11
- 外文名
- C11
- 曾用名
- C1X
- 標準編號
- ISO/IEC 9899:2011
- 發佈時間
- 2011年12月8日
- 發佈機構
- ISO/IEC JTC1/SC22/WG14
C11相比C99的變化
2. _Noreturn 函數標記,類似於 gcc 的 __attribute__((noreturn))。例子:
_Noreturn void thrd_exit(int res);
3. _Generic 關鍵詞,有點兒類似於 gcc 的 typeof。示例代碼:
#include<stdio.h> #define GENERAL_ABS(x)_Generic((x),int:abs,float:fabsf,double:fabs)(x) int main(void) { printf("intabs:%d\n",GENERAL_ABS(-12)); printf("floatabs:%f\n",GENERAL_ABS(-12.04f)); printf("doubleabs:%f\n",GENERAL_ABS(-13.09876)); int a=10; int b=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); }
_Static_assert(FOO > 0, "FOO has a wrong value");
5. 刪除了 gets() 函數,C99中已經將此函數被標記為過時,推薦新的替代函數 gets_s()。
7. 匿名結構體/聯合體,這個早已經在 gcc 中了,我們並不陌生,定義在 6.7.2.1 p13。
8. 多線程支持,包括:_Thread_local,頭文件 <threads.h>,裏面包含線程的創建和管理函數(比如 thrd_create(),thrd_exit()),mutex (比如 mtx_lock(),mtx_unlock())等等,更多內容清參考 7.26 節。
9. _Atomic類型修飾符和 頭文件 <stdatomic.h>,見 7.17 節。
10. 帶邊界檢查(Bounds-checking)的函數接口,定義了新的安全的函數,例如 fopen_s(),strcat_s() 等等。更多參考 Annex K。
11. 改進的 Unicode 支持,新的頭文件 <uchar.h> 等。實例代碼:
#include<stdio.h> #include<uchar.h> size_t UTF16StrLen(const char16_t *utf16String) { if(utf16String==NULL) return0; size_t index; for(index=0;utf16String[index]!=u'\0';index++); returnindex; } size_t UTF16ToUTF8(char *mbBuffer,const char16_t *utf16String) { if(mbBuffer==NULL||utf16String==NULL) return 0; mbstate_t state={}; size_t mbIndex=0; for(int utf16Index=0;utf16String[utf16Index]!=u'\0';utf16Index++) { constsize_tlength=c16rtomb(&mbBuffer[mbIndex],utf16String[utf16Index],&state); mbIndex+=length; } mbBuffer[mbIndex]='\0'; return mbIndex; } int main(int argc,char *argv[]) { char16_t ch=u'好'; char chBuffer[64]; mbstate_t state={}; size_t length=c16rtomb(chBuffer,ch,&state); chBuffer[length]='\0'; printf("TheUTF-8characterlengthis:%zu,andthecharacteris:%s\n",length,chBuffer); const char * utf8Str=u8"你好,世界。"; printf("TheUTF-8stringis:%s\n",utf8Str); const char16_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),具體見 7.22.4.7。
13. 創建複數的宏, CMPLX(),見 7.3.9.3。
14. 更多浮點數處理的宏 (More macros for querying the characteristics of floating point types, concerning subnormal floating point numbers and the number of decimal digits the type is able to store)。
15. struct timespec 成為 time.h 的一部分,以及宏 TIME_UTC,函數 timespec_get()。
C11C11還缺少什麼
1、對IEEE754標準-2008的半精度浮點數的支持。儘管遵循GNU C標準規範的編譯器(GCC以及Clang等)使用了C擴展關鍵字__fp16,但是隻能對半精度浮點數進行引用,而不能做任何算術操作。因此,這個特性應當在下一個C語言標準中立馬加入進去的,建議使用_Half作為半精度浮點數類型的關鍵字。
2、匿名函數:匿名函數,也叫lambda表達式,是現代計算機編程語言的一個典範特性,在Clang編譯器中已經通過blocks語法
[4]
進行了支持,該語法也被髮表到了下一代C標準的提案
[5-6]
。Lambda表達式非常適用於多核多線程並行計算,而不僅僅只是用於語法糖。
3、增加對UTF-16字符編碼字符串格式符的支持。在標準C語言中,直到C11還只能支持UTF-8編碼字符串的格式,採用%s。而對於UTF-16編碼字符串的各類操作都比較欠缺,而只有UTF-16轉UTF-8的庫函數c16rtomb以及UTF-8轉UTF-16的標準庫函數mbrtoc16可使用,因此在實際項目工程上,用起來十分繁瑣。這裏建議後續標準C語言採用%S表示UTF-16的字符串格式符,%s作為UTF-8字符串格式符,%C表示UTF-16字符,%c表示UTF-8字符。
- 參考資料
-
- 1. ISO/IEC 9899:2011 - Information technology -- Programming languages -- C .國際標準化組織(ISO - International Organization for Standardization).2011-12-08[引用日期2014-11-15]
- 2. ISO/IEC JTC1/SC22/WG14 - C: Approved standards .Open Standards.2011-04-12[引用日期2014-11-26]
- 3. ISO/IEC 9899:201x - N1570 - Programming languages - C .Open Standards.2011-04-12[引用日期2014-11-16]
- 4. Blocks編程話題 .Apple開發者網站[引用日期2014-11-16]
- 5. Blocks Proposal, N1451 .Open Standards.2010-04-13[引用日期2014-11-22]
- 6. WG14/N1370 Apple's Extensions to C .Open Standards.2009-03-10[引用日期2014-11-22]