Microsoft 對 C 和 C++ 的延伸模組

Microsoft Visual C++ (MSVC) 會以數種方式擴充 C 和 C++ 語言標準,本文詳述。

MSVC C++編譯程式默認支援 ISO C++14,其中包含一些 ISO C++17 功能和部分Microsoft特定語言延伸模組。 如需支援功能的詳細資訊,請參閱 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 編譯器支援下列範圍相關功能。

  • 將專案重新定義 externstatic

    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 編譯程式都支援內嵌產生 atanatan2log10sqrtexpsinlogcos和 函tan式。/Oi 這些內部函數不符合標準,因為它們不會設定 errno 變數。

ISO646.H 未啟用

在底下 /Ze,如果您想要使用下列運算子的文字形式,則必須包含 iso646.h

操作員 文字表單
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq

當指定或/permissive-隱含時/Za,這些文字窗體可做為C++關鍵詞。

另請參閱

/Za/Ze (停用語言延伸模組)
MSVC 編譯器選項
MSVC 編譯器命令列語法