Estensioni Microsoft a C e C++
Visual C++ consente di estendere ANSI C e C++ standard ANSI come segue.
Parole chiave
Diverse parole chiave aggiunti.Nell'elenco in Parole chiave C++, le parole chiave con due caratteri di sottolineatura e sono estensioni di Visual C++.
Definizione out of class di membri integrali const static (o enum)
In lo standard (/Za), è necessario fare una definizione di pronto utilizzo classe per i membri dati, come illustrato di seguito:
class CMyClass {
static const int max = 5;
int m_array[max];
}
...
const int CMyClass::max; // out of class definition
In /Ze la definizione out-of-class è facoltativa per membri dati static, const integral, e const enum.Solo gli integrali e le enumerazioni che sono statici e const possono avere inizializzatori nella classe, l'espressione tramite l'inizializzazione deve essere un'espressione const.
Per evitare errori quando una definizione di pronto utilizzo classe viene fornita in un file di intestazione e il file di intestazione è incluso in più file di origine, utilizzare selectany.Ad esempio:
__declspec(selectany) const int CMyClass::max = 5;
Cast
Il compilatore supporta questi tipi di cast non ANSI:
Cast Non ANSI per produrre valori l-value.Ad esempio:
char *p; (( int * ) p )++;
[!NOTA]
Questa estensione è disponibile nel linguaggio C solo.È possibile utilizzare il seguente formato di C standard ANSI nel codice C++ per modificare un puntatore come se fosse un puntatore a un tipo diverso.
L'esempio precedente può essere riscritto come segue per conformità allo standard ANSI C.
p = ( char * )(( int * )p + 1 );
Cast Non ANSI di un puntatore a funzione a un puntatore ai dati.Ad esempio:
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc;
Per eseguire lo stesso cast e anche per mantenere la compatibilità ANSI, è possibile eseguire il cast del puntatore a funzione di uintptr_t prima che sia stato eseguito il cast a un puntatore ai dati:
pdata = ( int * ) (uintptr_t) pfunc;
Elenchi di argomenti a lunghezza variabile
Il compilatore supporta una dichiarazione di funzione che specifica un numero variabile di argomenti, seguito da una definizione di funzione che fornisce un tipo anziché:
void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }
Commenti a riga singola
Il compilatore C supporta i commenti a riga singola, introdotti con due caratteri di barra (/):
// This is a single-line comment.
Ambito
Il compilatore C supporta le funzionalità seguenti ambito- correlate.
Ridefinizioni di voci extern come static:
extern int clip(); static int clip() {}
Utilizzo di ridefinizioni typedef benigna all'interno dello stesso ambito:
typedef int INT; typedef int INT;
I dichiaratori di funzione hanno un ambito di file:
void func1() { extern int func2( double ); } int main( void ) { func2( 4 ); // /Ze passes 4 as type double } // /Za passes 4 as type int
Utilizzare le variabili di ambito blocco e inizializzate con le espressioni non costanti:
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; }
Dichiarazioni e definizioni di dati
Il compilatore C supporta le funzionalità seguenti di dichiarazione e della definizione di dati.
Carattere misto e costanti stringa in un inizializzatore:
char arr[5] = {'a', 'b', "cde"};
Campi di bit con tipi di base diversa da unsigned int o di signed int.
Dichiaratori che non dispongono di una classe di archiviazione o un tipo:
x; int main( void ) { x = 1; }
Matrici non dimensionate come ultimo campo in strutture e unioni:
struct zero { char *c; int zarray[]; };
Strutture senza nome (anonime):
struct { int i; char *s; };
Unioni senza nome (anonime):
union { int i; float fl; };
Membri senza nome:
struct s { unsigned int flag : 1; unsigned int : 31; }
Funzioni a virgola mobile intrinseche
Il compilatore supporta la generazione inline x86 Specific > delle funzioni atan, atan2, cos, exp, log, log10, sin, sqrt e tanEND x86 Specific quando è specificata l'opzione /Oi.Per C, la conformità ANSI viene persa quando vengono utilizzate queste funzioni intrinseche in quanto non impostano la variabile errno.
Passaggio di un parametro del puntatore Non-Const a una funzione che prevede un riferimento a un parametro del puntatore Const
Questa è un'estensione a C++.Questo codice verrà compilato con /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 non attivato
In /Ze è necessario includere iso646.h se si desidera utilizzare formati di testo dei seguenti operatori:
&& (and)
&= (and_eq)
& (bitand)
| (bitor)
~ (compl)
!(not)
!= (not_eq)
|| (or)
|= (or_eq)
^ (xor)
^= (xor_eq)
L'indirizzo della stringa letterale è const [], non const del tipo (*) []
Nell'esempio riportato di seguito verrà restituito char const (*)[4] in /Za e char const [4] in /Ze.
#include <stdio.h>
#include <typeinfo>
int main()
{
printf_s("%s\n", typeid(&"abc").name());
}