Extensions Microsoft pour C et C++
Visual C++ étend les normes C ANSI et ANSI C++ comme suit.
Mots clés
Plusieurs mots clés sont ajoutés.Dans la liste dans Mots clés C++, les mots clés qui ont deux principaux traits de soulignement sont des extensions Visual C++.
Définition hors classe des membres static, const, integral (ou enum)
Sous la norme (/Za), vous devez effectuer une définition de classe pour les données membres, comme indiqué ci-après :
class CMyClass {
static const int max = 5;
int m_array[max];
}
...
const int CMyClass::max; // out of class definition
Sous /Ze, la définition hors classe est facultative pour les données membres static, const integral et const enum.Seuls les entier et les enums qui sont statiques et const peuvent avoir des initialiseurs dans une classe ; l'expression initialisante doit être une expression const.
Pour éviter les erreurs lorsqu'une définition de classe est fournie dans un fichier d'en-tête et le fichier d'en-tête est inclus dans plusieurs fichiers sources, utilisez selectany.Par exemple :
__declspec(selectany) const int CMyClass::max = 5;
Casts
Le compilateur prend en charge ces types de casts non ANSI :
Casts non ANSI pour produire l-value qu'.Par exemple :
char *p; (( int * ) p )++;
[!REMARQUE]
Cette extension est disponible dans le langage C uniquement.Vous pouvez utiliser la forme suivante de norme C ANSI dans le code C++ pour modifier un pointeur comme s'il s'agit d'un pointeur vers un type différent.
L'exemple précédent pourrait être réécrit comme suit pour être conforme à la norme C ANSI.
p = ( char * )(( int * )p + 1 );
Casts non ANSI d'un pointeur fonction à un pointeur donnée.Par exemple :
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc;
Pour exécuter le même cast et mettre à jour également compatibilité ANSI, vous pouvez effectuer un cast du pointeur fonction à uintptr_t avant de le mouliez à un pointeur donnée :
pdata = ( int * ) (uintptr_t) pfunc;
Listes d'arguments de longueur variable
Le compilateur prend en charge un déclarateur de fonction qui spécifie un nombre variable d'arguments, suivi d'une définition de fonction qui fournit un type à la place :
void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }
Commentaires sur une seule ligne
Le compilateur C prend en charge les commentaires sur une seule ligne, qui sont présentés à l'aide de deux caractères de barre oblique (/) :
// This is a single-line comment.
Portée
Le compilateur C en charge les fonctionnalités liées à la portée suivantes.
Redéfinitions des éléments externes (externe) en tant qu'éléments statiques (static) :
extern int clip(); static int clip() {}
Utilisation de redéfinitions typedef bénignes dans la même portée :
typedef int INT; typedef int INT;
Déclarateurs de fonction avec une portée de fichier :
void func1() { extern int func2( double ); } int main( void ) { func2( 4 ); // /Ze passes 4 as type double } // /Za passes 4 as type int
Utilisation de variables de portée de bloc qui sont initialisées à l'aide de expressions constantes non :
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; }
Définitions et déclarations de données
Le compilateur C en charge les fonctionnalités de déclaration et de définition de données suivante.
Combinaison de constantes de types caractère et chaîne dans un initialiseur :
char arr[5] = {'a', 'b', "cde"};
Champs de bits qui ont des types de base autres que unsigned int ou signed int.
Déclarateurs qui n'ont pas de classe de stockage ou un type :
x; int main( void ) { x = 1; }
Tableaux non dimensionnés comme dernier champ dans les structures et les unions :
struct zero { char *c; int zarray[]; };
Structures sans nom (anonymes) :
struct { int i; char *s; };
Unions sans nom (anonymes) :
union { int i; float fl; };
Membres sans nom :
struct s { unsigned int flag : 1; unsigned int : 31; }
Fonctions intrinsèques en virgule flottante
Le compilateur prend en charge la génération inline Spécifique x86 > des fonctions atan, atan2, cos, exp, log, log10, sin, sqrt et tanFIN xSpécifique x86 lorsque /Oi est spécifié.Pour C, la conformité ANSI n'est plus assurée quand ces fonctions intrinsèques sont utilisées, car elles ne définissent pas la variable errno.
Passage d'un paramètre pointeur non const à une fonction qui attend une référence à un paramètre pointeur const
Il s'agit d'une extension C++.Ce code compilera avec /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 n'est pas activé
Sous /Ze, vous devez inclure iso646.h si vous voulez utiliser les opérateurs suivants dans leur format texte :
&& (and)
&= (and_eq)
& (bitand)
| (bitor)
~ (compl)
!(not)
!= (not_eq)
|| (or)
|= (or_eq)
^ (xor)
^= (xor_eq)
L'adresse du littéral de chaîne a le type const char [], char non const (*) []
L'exemple suivant émet char const (*)[4] sous /Za, mais char const [4] sous /Ze.
#include <stdio.h>
#include <typeinfo>
int main()
{
printf_s("%s\n", typeid(&"abc").name());
}