Estensioni Microsoft a C e C++
Di seguito sono riportate le estensioni Visual C++ agli standard ANSI C e ANSI C++:
Parole chiave
Microsoft estende il linguaggio C++ con diverse parole chiave aggiuntive. Per un elenco completo, vedere C++ Keywords in Riferimenti del linguaggio C++. Le parole chiave con due caratteri di sottolineatura iniziali sono estensioni Microsoft.
Definizione out of class di membri integrali const static (o enum)
All'interno dello standard (/Za) è necessario effettuare una definizione out-of-class per i membri dati. Ad esempio,
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 gli enum che sono static e const possono avere inizializzatori all'interno di una classe. L'espressione che inizializza deve essere un'espressione const.
Per evitare errori quando viene fornita una definizione out-of-class, vale a dire quando viene fornita in un file di intestazione incluso in più file di origine, è necessario utilizzare selectany. Di seguito è riportato un esempio.
__declspec(selectany) const int CMyClass::max = 5;
Cast
Il compilatore supporta i seguenti due cast non ANSI:
Utilizzo di cast non ANSI per produrre valori I:
char *p; (( int * ) p )++;
L'esempio precedente potrebbe essere riscritto per essere conforme allo standard ANSI C nel modo seguente:
p = ( char * )(( int * )p + 1 );
Casting non ANSI di un puntatore a funzione a un puntatore di dati:
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc;
Per eseguire lo stesso cast pur conservando la compatibilità ANSI, è necessario eseguire il casting del puntatore a funzione a un int prima di eseguirne il casting a un puntatore dati:
pdata = ( int * ) (int) pfunc;
Elenchi di argomenti a lunghezza variabile
Il compilatore supporta l'utilizzo di un dichiaratore di funzione che specifica un numero variabile di argomenti, seguito da una definizione di funzione che fornisce invece un tipo:
void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }
Commenti a riga singola
Il compilatore C supporta commenti a riga singola, introdotti con due caratteri di barra (//):
// This is a single-line comment.
Ambito
Il compilatore C supporta le seguenti funzionalità relative all'ambito:
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
Utilizzo di variabili in ambito blocco inizializzate con 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 seguenti funzionalità di dichiarazione e definizione dei dati:
Carattere misto e costanti stringa in un inizializzatore:
char arr[5] = {'a', 'b', "cde"};
Campi bit con tipi di base diversi da unsigned int o signed int.
Dichiaratori senza una classe o un tipo di archiviazione:
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 tan END 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++. Il codice riportato di seguito eseguirà la compilazione 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 ha il tipo const char [], non const char (*) []
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());
}