Microsoft-extensies voor C en C++

Microsoft C++ (MSVC) breidt de C- en C++-taalstandaarden op verschillende manieren uit, zoals beschreven in dit artikel.

De MSVC C++-compiler biedt standaard ondersteuning voor ISO C++14 met enkele ISO C++17-functies en sommige Microsoft-specifieke taalextensies. Zie voor meer informatie over ondersteunde functies de taalconformance van Microsoft C/C++ per Visual Studio-versie. U kunt de /std compileroptie gebruiken om volledige ondersteuning in te schakelen voor ISO C++17- en ISO C++20-taalfuncties. Zie /std (Taalstandaardversie opgeven) voor meer informatie.

Indien opgegeven, kunnen sommige MSVC C++-taalextensies worden uitgeschakeld door gebruik te maken van de /Za compileroptie. In Visual Studio 2017 en hoger worden met de compileroptie /permissive- microsoft-specifieke C++-taalextensies uitgeschakeld. De /permissive- compileroptie wordt impliciet ingeschakeld door de /std:c++20 opties en /std:c++latest compileren.

Wanneer MSVC code compileert als C, wordt standaard ANSI C89 geïmplementeerd met microsoft-specifieke taalextensies. Sommige van deze MSVC-extensies zijn gestandaardiseerd in ISO C99 en hoger. De meeste MSVC C-extensies kunnen worden uitgeschakeld met behulp van de /Za compileroptie, zoals verderop in dit artikel wordt beschreven. U kunt de /std compileroptie gebruiken om ondersteuning voor ISO C11 en C17 in te schakelen. Zie /std (Taalstandaardversie opgeven) voor meer informatie.

De standaard-C-runtimebibliotheek wordt geïmplementeerd door de Universal C Runtime Library (UCRT) in Windows. Het UCRT implementeert ook veel POSIX- en Microsoft-specifieke bibliotheekextensies. Het UCRT ondersteunt de ISO C11- en C17 C-runtimebibliotheekstandaarden, met bepaalde implementatiespecifieke opmerkingen. Het biedt geen ondersteuning voor de volledige ISO C99 Standard C Runtime-bibliotheek. Zie de compatibiliteit in de documentatie van de Universal C-runtimebibliotheek voor meer informatie.

Zoekwoorden

MSVC voegt verschillende Microsoft-specifieke trefwoorden toe aan C en C++. In de lijst in Trefwoorden zijn de trefwoorden met twee voorloopstrepingstekens MSVC-extensies.

Werpt

Zowel de C++-compiler als de C-compiler ondersteunen dit soort niet-standaard casts:

  • De C-compiler ondersteunt niet-standaard casts om l-values te produceren. Voorbeeld:

    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
    

    Opmerking

    Deze extensie is alleen beschikbaar in de C-taal. U kunt het volgende standaardformulier voor C in C++-code gebruiken om een aanwijzer te wijzigen alsof deze een aanwijzer is naar een ander type.

    Het voorgaande voorbeeld kan als volgt worden herschreven om te voldoen aan de C-standaard.

    p = ( char * )(( int * )p + 1 );
    
  • Zowel de C- als C++-compilers ondersteunen niet-standaardcasts van een functiepointer naar een gegevenspointer. Voorbeeld:

    int ( * pfunc ) ();
    int *pdata;
    pdata = ( int * ) pfunc;
    /* No diagnostic at any level, whether compiled with default options or under /Za */
    

Lijsten met argumenten met variabele lengte

Zowel C- als C++-compilers ondersteunen een functiedeclarator die een variabel aantal argumenten opgeeft, gevolgd door een functiedefinitie die een type biedt:

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.

Opmerkingen met één regel

De C-compiler ondersteunt opmerkingen met één regel, die worden geïntroduceerd met behulp van twee slashtekens (//):

// This is a single-line comment.

Opmerkingen met één regel zijn een C99-functie. Ze worden niet beïnvloed door /Za en veroorzaken geen diagnose op elk niveau.

Scope

De C-compiler ondersteunt de volgende bereikgerelateerde functies.

  • Herdefinities van extern items als 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
    
  • Gebruik van goedaardige typedef-herdefinities binnen hetzelfde bereik:

    typedef int INT;
    typedef int INT; // No diagnostic at any level in C or C++
    
  • Functiedeclaraties hebben een bestandsbereik:

    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
    
  • Gebruik van variabelen met blokbereik die worden geïnitialiseerd met behulp van niet-constante expressies:

    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;
    }
    

Gegevensdeclaraties en definities

De C-compiler ondersteunt de volgende functies voor gegevensdeclaratie en definitie.

  • Gemengde teken- en tekenreeksconstanten in een initialisatiefunctie:

    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
    
  • Bitvelden met andere basistypen dan unsigned int of signed int.

  • Declaraties die geen type hebben:

    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;
    }
    
  • Niet-geconstrueerde matrices als laatste veld in structuren en samenvoegingen:

    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
    };
    
  • Naamloze (anonieme) structuren:

    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'
    
  • Niet-benoemde (anonieme) unions:

    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'
    

Intrinsieke drijvendekommafuncties

Zowel de x86 C++-compiler als de C-compiler ondersteunen inlinegeneratie van de atanfuncties , , logcoslog10expatan2, sinen sqrttan functies wanneer /Oi deze worden opgegeven. Deze intrinsieke waarden voldoen niet aan de standaard, omdat ze de errno variabele niet instellen.

ISO646.H niet ingeschakeld

Onder /Zemoet u opnemen iso646.h als u tekstvormen van de volgende operatoren wilt gebruiken:

Operator Tekstformulier
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq

Deze tekstformulieren zijn beschikbaar als C++-trefwoorden onder /Za of wanneer /permissive- deze worden opgegeven of geïmpliceerd.

Zie ook

/Za, /Ze (Taalextensies uitschakelen)
MSVC-compileropties
opdrachtregelsyntaxis van MSVC-compiler