Udostępnij za pośrednictwem


Rozszerzenia Microsoft do C i C++

Visual C++ rozszerza standardy ANSI C i ANSI C++ w następujący sposób.

Słowa kluczowe

Zostało dodanych kilka słów kluczowych.Na liście w Słowa kluczowe języka C++, słowa kluczowe, które mają dwa wiodące znaki podkreślenia są rozszerzeniami języka Visual C++.

Definicja poza klasą członków całkowitych static const (lub enum)

Zgodnie ze standardem (/Za), należy utworzyć definicję poza klasą dla elementów członkowskich danych, jak pokazano poniżej:

class CMyClass  {
   static const int max = 5;
   int m_array[max];
}
...
const int CMyClass::max;   // out of class definition

W /Ze, definicja poza klasą jest opcjonalna dla elementów członkowskich danych static, const integral i const enum.Tylko wartości całkowite i wyliczenia, które są statyczne i stałe, mogą mieć inicjatory w klasie; wyrażenie inicjujące musi być wyrażeniem stałym.

Aby uniknąć błędów, gdy dostarczona jest definicja poza klasą w pliku nagłówka i gdy plik nagłówka jest zawarty w wielu plikach źródłowych, należy użyć selectany.Na przykład:

__declspec(selectany) const int CMyClass::max = 5;

Rzutowania

Zarówno kompilator języka C++ jak i kompilator języka C obsługują te rodzaje rzutowania nie ANSI:

  • Rzutowania nie ANSI do produkcji l-wartości.Na przykład:

    char *p;
    (( int * ) p )++;
    

    [!UWAGA]

    To rozszerzenie jest dostępne tylko w języku C.Można użyć następującej formy standardu ANSI C w kodzie C++ do modyfikowania wskaźnika tak, jakby był wskaźnikiem do innego typu.

    Poprzedni przykład mógł być przepisany w następujący sposób do standardu ANSI C.

    p = ( char * )(( int * )p + 1 );
    
  • Rzutowania nie ANSI wskaźnika funkcji do wskaźnika danych.Na przykład:

    int ( * pfunc ) (); 
    int *pdata;
    pdata = ( int * ) pfunc;
    

    Aby wykonać to samo rzutowanie i zachować zgodność ANSI, można wykonać rzutowanie wskaźnika funkcji do uintptr_t przed rzutowaniem go na wskaźnik danych:

    pdata = ( int * ) (uintptr_t) pfunc;
    

Listy argumentów o zmiennej długości

Zarówno kompilator języka C++ i kompilator języka C obsługuje deklarator funkcji, który określa zmienną liczbę argumentów, po czym następuje definicja funkcji, która w zamian zapewnia typ:

void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }

Komentarze jednowierszowe

Kompilator języka C obsługuje komentarze jednowierszowe, które są wprowadzane przy użyciu dwóch znaków ukośnika (//):

// This is a single-line comment.

Zakres

Kompilator języka C obsługuje następujące funkcje związane z zakresem.

  • Ponowne definicje elementów zewnętrznych jako statyczne:

    extern int clip();
    static int clip()
    {}
    
  • Użycie korzystnych ponownych definicji typu w tym samym zakresie:

    typedef int INT;
    typedef int INT;
    
  • Deklaratory funkcji mają zakres pliku:

    void func1()
    {
        extern int func2( double );
    }
    int main( void )
    {
        func2( 4 );    //  /Ze passes 4 as type double
    }                  //  /Za passes 4 as type int
    
  • Użycie zmiennych o zakresie bloku, które są zainicjowane za pomocą wyrażeń nie stałych:

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

Deklaracje i definicje danych

Kompilator języka C obsługuje następujące deklaracje danych i funkcje definicji.

  • Mieszane stałe znaki i ciągi w inicjatorze:

    char arr[5] = {'a', 'b', "cde"};
    
  • Pola bitowe, które mają typy podstawowe inne niż unsigned int lub signed int.

  • Deklaratory, które nie mają typu:

    x;
    int main( void )
    {
        x = 1;
    }
    
  • Tablice bez określonego rozmiaru jako ostatnie pole w strukturach i związkach:

    struct zero
    {
        char *c;
        int zarray[];
    };
    
  • Struktury nienazwane (anonimowe):

    struct
    {
        int i;
        char *s;
    };
    
  • Związki nienazwane (anonimowe):

    union
    {
        int i;
        float fl;
    };
    
  • Nienazwane elementy członkowskie:

    struct s
    {
       unsigned int flag : 1;
       unsigned int : 31;
    }
    

Wewnętrzne funkcje zmiennoprzecinkowe

Kompilator języka C++ i kompilator języka C obsługują generowanie w tekście właściwe dla procesora x86 > funkcje atan, atan2, cos, exp, log, log10, sin, sqrt i tanKONIEC właściwe dla procesora x86 w razie określenia /Oi.Dla kompilatora języka C, zgodność ANSI jest tracona, kiedy używane są te funkcje wewnętrzne, ponieważ nie ustawiają one zmiennej errno.

Przekazywanie nie stałego parametru wskaźnika do funkcji, która oczekuje odwołania do stałego parametru wskaźnika

Jest to rozszerzenie języka C++.Ten kod zostanie skompilowany z użyciem /Ze:

typedef   int   T;

const T  acT = 9;      // A constant of type 'T'
const T* pcT = &acT;   // A pointer to a constant of type 'T'

void func2 ( const T*& rpcT )   // A reference to a pointer to a constant of type 'T'
{
   rpcT = pcT;
}

T*   pT;               // A pointer to a 'T'

void func ()
{
   func2 ( pT );      // Should be an error, but isn't detected
   *pT   = 7;         // Invalidly overwrites the constant 'acT'
}

ISO646.H Nie włączone

Przy /Ze, należy dołączyć iso646.h, jeśli chcesz używać postaci tekstowych następujących operatorów:

  • && (and)

  • &= (and_eq)

  • & (bitand)

  • | (bitor)

  • ~ (compl)

  • ! (not)

  • != (not_eq)

  • || (or)

  • |= (or_eq)

  • ^ (xor)

  • ^= (xor_eq)

Adres literału ciągu jest typu const char [], a nie const char (*) []

Poniższy przykład spowoduje wygenerowanie char const (*)[4] dla /Za, ale char const [4] dla /Ze.

#include <stdio.h>
#include <typeinfo>

int main()
{
    printf_s("%s\n", typeid(&"abc").name());
}

Zobacz też

Informacje

/Za, /Ze (Wyłącz rozszerzenia językowe)

Opcje kompilatora

Ustawianie opcji kompilatora