雖然沒(méi)有固定標(biāo)準(zhǔn),但一般將C99之后的C語(yǔ)言標(biāo)準(zhǔn)稱為“現(xiàn)代C語(yǔ)言”,目前的最新標(biāo)準(zhǔn)為C23。C語(yǔ)言的演化包括標(biāo)準(zhǔn)C89、C90、C99、C11、C17和C23,C23是C語(yǔ)言標(biāo)準(zhǔn)的一次重大修訂,截至2024年3月,最新版本的gcc和clang實(shí)現(xiàn)了C23的大部分新語(yǔ)言功能,但是部分功能仍然缺失,例如:constexpr 存儲(chǔ)類說(shuō)明符,[[unsequenced]] 和 [[reproducible]] 屬性等等。以下是比較重要的變化,完整變化列表可以參閱https://en./w/c/23 或ISO標(biāo)準(zhǔn)文檔。 一. 替代<assert.h> 中的static_assert() 宏被替代,變成了static_assert 關(guān)鍵字;<threads.h> 中的thread_local() 宏被替代,變成了thread_local 關(guān)鍵字;<time.h> 中的ctime() 函數(shù)棄用,請(qǐng)使用ctime_s() 替代;<time.h> 中的asctime() 函數(shù)棄用,請(qǐng)使用asctime_s() 替代;<stdnoreturn.h> 與_Noreturn 標(biāo)識(shí)符均棄用;<stdalign.h> 中的alignas() 和alignof() 宏被棄用,請(qǐng)直接使用_Alignas 和_Alignof 關(guān)鍵字;
二. 新增DEC32_MAX 9.999999E96DFDEC64_MAX 9.999999999999999E384DDDEC128_MAX 9.999999999999999999999999999999999E6144DL
- C23的字面量可以加分隔符了,增強(qiáng)可讀性,例如:
void func(int a, nullptr_t b) { //... }
func(10, nullptr);
int *a = nullptr;
if(!a) { printf('A is nullptr'); }
[[deprecated]] [[nodiscard]] [[noreturn]] [[maybe_unused]]
#elifdef #elifndef #warning:讓編譯器拋出警告 #embed:讓編譯器直接內(nèi)嵌二進(jìn)制數(shù)據(jù) #ifdef FOO /* stuff if there is a defined FOO */ #elifdef BAR /* stuff if there is a defined BAR */ #elifndef BAZ /* stuff if there is NO defined BAZ */ #else /* stuff as the last resort */ #endif
static const char song[] = { #embed <music.wav> // 內(nèi)嵌二進(jìn)制文件數(shù)據(jù) };
int a[5] = { 0 }; // 可以直接寫成 int a[5] = {}; // 等價(jià)于 int a[5] = { 0, 0, 0, 0, 0 };
C23的宏支持__VA_OPT__了,能更方便地解決使用宏時(shí)末尾符號(hào)的問(wèn)題 C23給<stdio.h>中的printf()函數(shù)添加了%b和%B支持,能像打印16進(jìn)制(%x %X)一樣直接打印二進(jìn)制數(shù)據(jù)了;scanf()也增加了%b支持 C23給<string.h>增加了memccpy(),與memcpy()類似但遇到某個(gè)特定值時(shí)會(huì)立刻停止復(fù)制 C23給<string.h>增加了strdup()與strndup(),用于復(fù)制出一個(gè)新的(部分)字符串 C23引入了函數(shù)定義時(shí)的匿名參數(shù),如果一個(gè)參數(shù)因?yàn)槟撤N原因必須被傳遞但卻不被使用,就可以把它設(shè)置為匿名參數(shù):
int func(int num, char*) { return num + 5; }
const char* func() { return 'Hello!'; }
auto ret = func();
// 12位無(wú)符號(hào)整數(shù) unsigned _BitInt(12) a = 0uwb;
enum flags: unsigned long { err1 = 0xCOOOFFFF; err2 = 0xC0010000; }
int a = 10; typeof(a) b = 5;
三. 刪除<stdlib.h>中的realloc()不再支持size為0的情況,改為未定義行為; C23取消了對(duì)三字母詞(Trigraph)的支持。三字母詞是一種轉(zhuǎn)義字符,由??開(kāi)頭。例如在字面量中使用??)代替]。 C23規(guī)定整數(shù)必須使用補(bǔ)碼存儲(chǔ),不應(yīng)再使用原碼和反碼; C23決定不再支持K&R格式。K&R格式是一種老式C語(yǔ)言寫法,例如:
// K&R int func1(a, b, c) int a; char* b; int c; { return a + c; }
// 等價(jià)于現(xiàn)代語(yǔ)法 int func1(int a, char* b, int c) { return a + c; }
參考: Modern C :https://inria.ience/hal-02383654 C23 :http://cpp./zh/c/23.html
|