Partager via


Microsoft Extensions to C and C++

The following are Visual C++ extensions to the ANSI C and ANSI C++ standards:

Keywords

Microsoft extends the C++ language with several additional keywords. For a complete list, see The C++ Language Reference. Keywords with two leading underscores are Microsoft extensions.

Windows CE .NET supports the __based, __finally, and __try keywords.

Out of Class Definition of static const Integral (or enum) Members

Under the standard /Za - Disable Language Extensions, you need to make an out-of-class definition for data members. For example,

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

Under /Ze - Enable Language Extensions, the out-of-class definition is optional for static, constintegral, and constenum data members. Only integrals and enums that are static and const can have initializers inside a class; the initializing expression must be a const expression.

To avoid errors when a header file provides an out-of-class definition and when multiple source files include the header file, you should use selectany. For example:

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

Casts

The compiler supports the following two non-ANSI casts:

  • Non-ANSI casts to produce l-values:

    char *p;
    (( int * ) p )++;
    
  • Non-ANSI casting of a function pointer to a data pointer:

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

    To perform the same cast while maintaining ANSI compatibility, you must cast the function pointer to an int before casting it to a data pointer:

    pdata = ( int * ) (int) pfunc;
    

Variable-Length Argument Lists

The compiler supports use of a function declarator that specifies a variable number of arguments, followed by a function definition that provides a type instead:

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

Single-Line Comments

The C compiler supports single-line comments introduced with two forward slash (//) characters:

// This is a single-line comment.

Scope

The C compiler supports the following scope-related features:

  • Redefinitions of extern items as static:

    extern int clip();
    static int clip()
    {}
    
  • Use of benign typedef redefinitions within the same scope:

    typedef int INT;
    typedef int INT;
    
  • File scope for function declarators:

    void func1()
    {
        extern int func2( double );
    }
    void main( void )
    {
        func2( 4 );    //  /Ze passes 4 as type double
    }                  //  /Za passes 4 as type int
    
  • Use of block-scope variables initialized with nonconstant expressions:

    int clip( int );
    int bar( int );
    void main( void )
    {
        int array[2] = { clip( 2 ), bar( 4 ) };
    }
    int clip( int x )
    {
        return x;
    }
    int bar( int x )
    {
        return x;
    }
    

Data Declarations and Definitions

The C compiler supports the following data declaration and definition features:

  • Mixed character and string constants in an initializer:

    char arr[5] = {'a', 'b', "cde"};
    
  • Bit fields with base types other than unsigned int or signed int.

  • Declarators without either a storage class or a type:

    x;
    void main( void )
    {
        x = 1;
    }
    
  • Unsized arrays as the last field in structures and unions:

    struct zero
    {
        char *c;
        int zarray[];
    };
    
  • Unnamed, anonymous structures:

    struct
    {
        int i;
        char *s;
    };
    
  • Unnamed, anonymous unions:

    union
    {
        int i;
        float fl;
    };
    
  • Unnamed members:

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

Intrinsic Floating-Point Functions

The compiler supports inline generation of the atan, atan2, cos, exp, log, log10, sin, sqrt, and tan functions. Function generation is specific with /Oi - Generate Intrinsic Functions. For C, ANSI conformance is lost when these intrinsics are used.

Passing a Non-Const Pointer Parameter to a Function that Expects a Reference to a Const Pointer Parameter

This is an extension to C++. The following code will compile with /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'
}

new Operator Does Not Throw Exception

If the new operator fails to allocate requested memory, no exception will be thrown; a null pointer is returned instead.

Scope of Variable in for Loop Stays in Effect After Loop

The following code will compile under /Za. However, to keep compatibility with older code bases, it will not compile under /Ze:

int main () {
   for (int i = 0; i<1; ++i);
   for (int i = 0; i<1; ++i);
   return 0;
}

ISO646.H Not Enabled

Under /Ze, you have to include iso646.h if you want to use text forms of the following operators:

  • && (and)
  • &= (and_eq)
  • & (bitand)
  • | (bitor)
  • ~ (compl)
  • ! (not)
  • != (not_eq)
  • || (or)
  • |= (or_eq)
  • ^ (xor)
  • ^= (xor_eq)

See Also

/Za - Disable Language Extensions | /Ze - Enable Language Extensions | Compiler Options | Compiler Setup Mechanisms

 Last updated on Thursday, April 08, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.