MSVC宣布支持C11和C17標準
日前微軟VS團隊宣布,將在Visual Studio 2019版本16.8預覽版3開始,正式支持C11和C17為MSVC編譯器。多年來,Visual Studio僅在C++要求的范圍內支持C。隨著兩個新的編譯器開關/std:c11和/std:c17的出現,VS將正式支持最新的ISO C語言標準。

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

IntelliSense高亮僅適用于關鍵字,不適用于標準標頭引入的宏。由于C17本質上只是ISO C的錯誤修復版本,并且采用了許多缺陷報告,因此對C11的支持已經包括所有相關的缺陷報告。目前,C11和C17版本之間沒有什么區別,除了__STDC_VERSION__宏,該宏擴展為201112L(對于C11)和201710L(對于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);
- }
由于包含了基于令牌的一致性預處理器,因此這兩個新的C編譯器開關暗示/Zc:preprocessor。如果要與C11或C17一起使用基于字符的傳統預處理器,則需要顯式傳遞編譯器開關/Zc:preprocessor-。
盡管目前不支持任何C11可選功能,會在將來的版本中提供最具影響力的可選功能。原子和線程支持在我們的路線圖上。目前尚不支持對復數的支持,并且通過適當的功能測試宏來強制不支持復數。
由于Windows堆的性質,缺少對aligned_alloc的支持。另一種方法是使用_aligned_malloc。
此外,由于realloc更改可能會破壞ABI,因此目前尚未實現DR 400支持。
同時也不支持VLA。可變長度數組通常比可比的固定大小數組效率低,并且在安全可靠地實現時,與等效數組相比效率通常較低。VLA存在gets()安全問題,可以被 "轉移堆棧"和其他的利用。由于這些原因,VLA支持僅僅為可選功能。
基本設置
為了在程序中使用C11或C17,需要最新的Windows SDK更新才能與兼容的預處理器(/Zc:preprocessor)并在新的Universal C Runtime下工作。Windows SDK版本與Windows OS版本相對應。由于沒有更改對應的Windows版本,因此需要一個Insider Preview Windows SDK-Windows SDK的預覽版本,該版本與當前為Windows Insiders發行的Windows版本相對應。注意,在安裝Insider Preview Windows 10 SDK之后,配置為使用最新Windows SDK的Visual Studio項目將使用Insider Preview。
登陸Microsoft Insider
任何人都可以創建一個免費的Microsoft帳戶,然后選擇加入Insider程序, "注冊"并登錄。

注冊后,將提供開始運行Insider版本的Windows的選項,但是下載和使用Insider Windows 10 SDK是非必須的。

一旦你點擊這個頁面,你就不會需要點擊"Flight now"。繼續進行下一步,并下載Insider Preview Windows 10 SDK。
下載Insider Preview Windows 10 SDK
可以從software-download/windowsinsiderpreviewSDK安裝Insider Preview Windows SDK。

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

掛載.iso文件并運行WinSDKSetup.exe以開始安裝。

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

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

將能看到一個新選項:C語言標準。

當語言為C++時使用C++語言標準,當文件擴展名為.cpp為默認設置。當語言為C時,使用C語言標準版本,擴展名為.c,默認c版本。為確保使用C11或C17構建項目,必須確保它是文件,或在"屬性"選項卡中將代碼設置為編譯為C。

這些項目更改之后,就可以測試使用C11和C17。
總結
支持C11和C17,這對使用VS Windows的開發者來說是個好消息,希望大家嘗鮮使用。