Microsoft 對 C 和 C++ 的延伸模組
Microsoft Visual C++ (MSVC) 以數種方式擴充 C 和 C++ 語言標準,本文詳述。
MSVC C++ 編譯器預設支援具有某些 ISO C++17 功能和某些 Microsoft 特定語言延伸模組的 ISO C++14。 如需支援功能的詳細資訊,請參閱 Visual Studio 版本的 Microsoft C/C++ 語言一致性。 您可以使用編譯 /std
程式選項來啟用 ISO C++17 和 ISO C++20 語言功能的完整支援。 如需詳細資訊,請參閱 /std
(指定語言標準版本)。
如指定,可以使用編譯器選項來 /Za
停用某些 MSVC C++ 語言延伸模組。 在 Visual Studio 2017 和更新版本中,編譯 /permissive-
程式選項會停用 Microsoft 特定的 C++ 語言延伸模組。 和 /std:c++latest
編譯器選項會隱含啟用 /std:c++20
編譯 /permissive-
程式選項。
根據預設,當 MSVC 將程式碼編譯為 C 時,它會使用 Microsoft 特定的語言延伸模組來實作 ANSI C89。 其中有些 MSVC 延伸模組在 ISO C99 和更新版本中已標準化。 大部分的 MSVC C 擴充功能都可以使用 /Za
編譯器選項來停用,如本文稍後所述。 您可以使用編譯 /std
程式選項來啟用 ISO C11 和 C17 的支援。 如需詳細資訊,請參閱 /std
(指定語言標準版本)。
標準 C 執行時間程式庫是由 Windows 中的通用 C 執行時間程式庫 (UCRT) 實作。 UCRT 也會實作許多 POSIX 和 Microsoft 特定的程式庫延伸模組。 UCRT 支援 ISO C11 和 C17 C 執行時間程式庫標準,具有特定實作特定的注意事項。 它不支援完整的 ISO C99 標準 C 執行時間程式庫。 如需詳細資訊,請參閱 通用 C 執行時間程式庫檔中的相容性 。
關鍵字
MSVC 會將數個 Microsoft 特定關鍵字新增至 C 和 C++。 在關鍵字 清單中 ,具有兩個前置底線的關鍵字是 MSVC 延伸模組。
轉型
C++ 編譯器和 C 編譯器都支援這類非標準轉換:
C 編譯器支援非標準轉換,以產生 l 值。 例如:
char *p; (( int * ) p )++; // In C with /W4, both by default and under /Ze: // warning C4213: nonstandard extension used: cast on l-value // Under /TP or /Za: // error C2105: '++' needs l-value
注意
此擴充功能只能在 C 語言中使用。 您可以在 C++ 程式碼中使用下列 C 標準表單來修改指標,就好像它是不同類型的指標一樣。
上述範例可以重寫如下,以符合 C 標準。
p = ( char * )(( int * )p + 1 );
C 和 C++ 編譯器都支援資料指標之函式指標的非標準轉換。 例如:
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc; /* No diagnostic at any level, whether compiled with default options or under /Za */
可變長度引數清單
C 和 C++ 編譯器都支援指定引數數目的函式宣告子,後面接著提供型別的函式定義:
void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }
// In C with /W4, either by default or under /Ze:
// warning C4212: nonstandard extension used: function declaration used ellipsis
// In C with /W4, under /Za:
// warning C4028: formal parameter 2 different from declaration
// In C++, no diagnostic by default or under /Za.
單行註解
C 編譯器支援單行批註,這是使用兩個正斜線 ( //
) 字元所引進:
// This is a single-line comment.
單行批註是 C99 功能。 它們不受任何 /Za
影響,而且在任何層級都不會造成任何診斷。
範圍
C 編譯器支援下列範圍相關功能。
將專案重新定義
extern
為static
:extern int clip(); static int clip() {} // In C and C++ with /W4, either by default or under /Ze: // warning C4211: nonstandard extension used: redefined extern to static // In C and C++ under /Za: // error C2375: 'clip': redefinition; different linkage
在相同範圍內使用良性 typedef 重新定義:
typedef int INT; typedef int INT; // No diagnostic at any level in C or C++
函式宣告子具有檔案範圍:
void func1() { extern double func2( double ); // In C at /W4: warning C4210: nonstandard extension used: function given file scope } int main( void ) { func2( 4 ); // /Ze passes 4 as type double } // /Za passes 4 as type int
使用非常數運算式初始化的區塊範圍變數:
int clip( int ); int bar( int ); int main( void ) { int array[2] = { clip( 2 ), bar( 4 ) }; } int clip( int x ) { return x; } int bar( int x ) { return x; }
資料宣告和定義
C 編譯器支援下列資料宣告和定義功能。
初始化運算式中的混合字元和字串常數:
char arr[6] = {'a', 'b', "cde"}; // In C with /W4, either by default or under /Ze: // warning C4207: nonstandard extension used: extended initializer form // Under /Za: // error C2078: too many initializers
具有 或
signed int
以外的unsigned int
基底類型的位欄位。沒有類型的宣告子:
x; // By default or under /Ze, /Za, /std:c11, and /std:c17, when /W4 is specified: // warning C4431: missing type specifier - int assumed. Note: C no longer supports default-int // warning C4218: nonstandard extension used: must specify at least a storage class or a type */ int main( void ) { x = 1; }
未化的陣列作為結構和等位的最後一個欄位:
struct zero { char *c; int zarray[]; // In C with /W4, either by default, under /Ze, /std:c11, and /std:c17: // warning C4200: nonstandard extension used: zero-sized array in struct/union // Under /Za: // error C2133: 'zarray': unknown size };
未命名(匿名)結構:
struct { int i; char *s; }; // By default or under /Ze, /std:c11, and /std:c17, when /W4 is specified: // warning C4094: untagged 'struct' declared no symbols // Under /Za: // error C2059: syntax error: 'empty declaration'
未命名(匿名)等位:
union { int i; float fl; }; // By default or under /Ze, /std:c11, and /std:c17, when /W4 is specified: // warning C4094: untagged 'union' declared no symbols // Under /Za: // error C2059: syntax error: 'empty declaration'
內建浮點函式
當指定 時,x86 C++ 編譯器和 C 編譯器都支援內嵌產生 atan
、 cos
atan2
、 exp
、、 log
、、 sqrt
sin
log10
和 函 tan
式。 /Oi
這些內建函式不符合標準,因為它們不會設定 errno
變數。
ISO646.H
未啟用
在 底下 /Ze
,如果您想要使用下列運算子的文字形式,則必須包含 iso646.h
:
運算子 | 文字表單 |
---|---|
&& |
and |
&= |
and_eq |
& |
bitand |
| |
bitor |
~ |
compl |
! |
not |
!= |
not_eq |
|| |
or |
|= |
or_eq |
^ |
xor |
^= |
xor_eq |
當指定或隱含時 /permissive-
,這些文字表單會以 C++ 關鍵字 /Za
的形式提供。
另請參閱
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: