MSVC宣布支持C11和C17標(biāo)準(zhǔn)
日前微軟VS團(tuán)隊(duì)宣布,將在Visual Studio 2019版本16.8預(yù)覽版3開(kāi)始,正式支持C11和C17為MSVC編譯器。多年來(lái),Visual Studio僅在C++要求的范圍內(nèi)支持C。隨著兩個(gè)新的編譯器開(kāi)關(guān)/std:c11和/std:c17的出現(xiàn),VS將正式支持最新的ISO C語(yǔ)言標(biāo)準(zhǔn)。

概述
支持C11和C17的所有必需功能,將會(huì)添加這些功能:_Pragma,restrict,_Noreturn和
IntelliSense本身也具有這些功能,只需為源文件使用.c文件擴(kuò)展名或/TC編譯器開(kāi)關(guān)即可為C代碼啟用語(yǔ)法突出顯示。

IntelliSense高亮僅適用于關(guān)鍵字,不適用于標(biāo)準(zhǔn)標(biāo)頭引入的宏。由于C17本質(zhì)上只是ISO C的錯(cuò)誤修復(fù)版本,并且采用了許多缺陷報(bào)告,因此對(duì)C11的支持已經(jīng)包括所有相關(guān)的缺陷報(bào)告。目前,C11和C17版本之間沒(méi)有什么區(qū)別,除了__STDC_VERSION__宏,該宏擴(kuò)展為201112L(對(duì)于C11)和201710L(對(duì)于C17)。
這是顯示這些功能的示例:
- #include <assert.h>
- #include <stdalign.h>#include <stdlib.h>#include <stdnoreturn.h>#define NO_WARN(X) _Pragma("warning (push)") _Pragma("warning (disable: 4146)") X; _Pragma("warning (pop)")
- #define store(x, y) _Generic((x), data*: stored, int* : storei)(x, y)
- typedef struct data {
- _Alignas(8) unsigned int i;
- } data;
- static_assert(alignof(data) == 8, "data is not properly aligned");
- void stored(data* restrict dst, const data* restrict src)
- {// Do not trigger warning 4245
- dst->i = NO_WARN(-(src->i));
- }
- void storei(int* restrict dst, const int* restrict src)
- {
- *dst = *src;
- }
- noreturn void my_exit(int ret) {
- exit(ret);
- }
- int main() {
- data src, dst;
- src.i = 5;
- int i, j;
- i = 10;
- store(&src, &dst);
- store(&i, &j);
- my_exit(0);
- }
由于包含了基于令牌的一致性預(yù)處理器,因此這兩個(gè)新的C編譯器開(kāi)關(guān)暗示/Zc:preprocessor。如果要與C11或C17一起使用基于字符的傳統(tǒng)預(yù)處理器,則需要顯式傳遞編譯器開(kāi)關(guān)/Zc:preprocessor-。
盡管目前不支持任何C11可選功能,會(huì)在將來(lái)的版本中提供最具影響力的可選功能。原子和線程支持在我們的路線圖上。目前尚不支持對(duì)復(fù)數(shù)的支持,并且通過(guò)適當(dāng)?shù)墓δ軠y(cè)試宏來(lái)強(qiáng)制不支持復(fù)數(shù)。
由于Windows堆的性質(zhì),缺少對(duì)aligned_alloc的支持。另一種方法是使用_aligned_malloc。
此外,由于realloc更改可能會(huì)破壞ABI,因此目前尚未實(shí)現(xiàn)DR 400支持。
同時(shí)也不支持VLA。可變長(zhǎng)度數(shù)組通常比可比的固定大小數(shù)組效率低,并且在安全可靠地實(shí)現(xiàn)時(shí),與等效數(shù)組相比效率通常較低。VLA存在gets()安全問(wèn)題,可以被 "轉(zhuǎn)移堆棧"和其他的利用。由于這些原因,VLA支持僅僅為可選功能。
基本設(shè)置
為了在程序中使用C11或C17,需要最新的Windows SDK更新才能與兼容的預(yù)處理器(/Zc:preprocessor)并在新的Universal C Runtime下工作。Windows SDK版本與Windows OS版本相對(duì)應(yīng)。由于沒(méi)有更改對(duì)應(yīng)的Windows版本,因此需要一個(gè)Insider Preview Windows SDK-Windows SDK的預(yù)覽版本,該版本與當(dāng)前為Windows Insiders發(fā)行的Windows版本相對(duì)應(yīng)。注意,在安裝Insider Preview Windows 10 SDK之后,配置為使用最新Windows SDK的Visual Studio項(xiàng)目將使用Insider Preview。
登陸Microsoft Insider
任何人都可以創(chuàng)建一個(gè)免費(fèi)的Microsoft帳戶,然后選擇加入Insider程序, "注冊(cè)"并登錄。

注冊(cè)后,將提供開(kāi)始運(yùn)行Insider版本的Windows的選項(xiàng),但是下載和使用Insider Windows 10 SDK是非必須的。

一旦你點(diǎn)擊這個(gè)頁(yè)面,你就不會(huì)需要點(diǎn)擊"Flight now"。繼續(xù)進(jìn)行下一步,并下載Insider Preview Windows 10 SDK。
下載Insider Preview Windows 10 SDK
可以從software-download/windowsinsiderpreviewSDK安裝Insider Preview Windows SDK。

Insider頁(yè)面描述了需要使用Windows 10 Insider Preview OS。對(duì)于Windows SDK中包含的某些內(nèi)容,這是正確的,取決于Windows的較早版本中不存在的新API,但是Windows和Universal C Runtime標(biāo)頭將正確安裝并且在沒(méi)有Insider OS的情況下可用。
點(diǎn)擊"獲取SDK Insider預(yù)覽-內(nèi)部版本20206"開(kāi)始下載。Windows SDK的將來(lái)版本也將起作用。
安裝Insider Preview Windows 10 SDK
Insider Preview Windows SDK將作為.iso文件下載。

掛載.iso文件并運(yùn)行WinSDKSetup.exe以開(kāi)始安裝。

選擇在計(jì)算機(jī)上安裝Windows軟件開(kāi)發(fā)套件,然后單擊下一步。必須選擇是否允許深入了解Windows SDK的使用,并且必須接受許可協(xié)議,然后才能到達(dá)功能部件安裝頁(yè)面。應(yīng)該安裝的唯一功能(除非使用Windows 10的Insider Preview構(gòu)建):
- 適用于桌面應(yīng)用程序的Windows SDK簽名工具
- 適用于UWP托管應(yīng)用程序的Windows SDK
- 適用于UWP C ++應(yīng)用程序的Windows SDK
- Windows SDK for Desktop C++ x86應(yīng)用程序(為x86進(jìn)行構(gòu)建)
- Windows SDK for Desktop C++ arm64應(yīng)用程序(為arm64構(gòu)建)
- Windows SDK for Desktop C++ ARM應(yīng)用程序(為ARM構(gòu)建)

SDK將花費(fèi)幾分鐘的時(shí)間來(lái)完成安裝,然后就可以打開(kāi)Visual Studio 16.8 Preview 3。
配置C11或C17模式
為了在Visual Studio 16.8 Preview 3中支持C11和C17。可以直接載最新的Preview版本。
在項(xiàng)目中,打開(kāi)"屬性"頁(yè)面。確保該項(xiàng)目將使用Insiders Preview Window 10 SDK。將Windows SDK版本設(shè)置為10.0.20206.0(或剛剛安裝的最新的Insider Preview Windows 10 SDK)。

將能看到一個(gè)新選項(xiàng):C語(yǔ)言標(biāo)準(zhǔn)。

當(dāng)語(yǔ)言為C++時(shí)使用C++語(yǔ)言標(biāo)準(zhǔn),當(dāng)文件擴(kuò)展名為.cpp為默認(rèn)設(shè)置。當(dāng)語(yǔ)言為C時(shí),使用C語(yǔ)言標(biāo)準(zhǔn)版本,擴(kuò)展名為.c,默認(rèn)c版本。為確保使用C11或C17構(gòu)建項(xiàng)目,必須確保它是文件,或在"屬性"選項(xiàng)卡中將代碼設(shè)置為編譯為C。

這些項(xiàng)目更改之后,就可以測(cè)試使用C11和C17。
總結(jié)
支持C11和C17,這對(duì)使用VS Windows的開(kāi)發(fā)者來(lái)說(shuō)是個(gè)好消息,希望大家嘗鮮使用。