Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this article
Microsoft Visual C++ (MSVC) extends the C and C++ language standards in several ways, detailed in this article.
The MSVC C++ compiler defaults to support for ISO C++14 with some ISO C++17 features and some Microsoft-specific language extensions. For more information on supported features, see Microsoft C/C++ language conformance by Visual Studio version. You can use the /std
compiler option to enable full support for ISO C++17 and ISO C++20 language features. For more information, see /std
(Specify language standard version).
Where specified, some MSVC C++ language extensions can be disabled by use of the /Za
compiler option. In Visual Studio 2017 and later versions, the /permissive-
compiler option disables Microsoft-specific C++ language extensions. The /permissive-
compiler option is implicitly enabled by the /std:c++20
and /std:c++latest
compiler options.
By default, when MSVC compiles code as C, it implements ANSI C89 with Microsoft-specific language extensions. Some of these MSVC extensions are standardized in ISO C99 and later. Most MSVC C extensions can be disabled by use of the /Za
compiler option, as detailed later in this article. You can use the /std
compiler option to enable support for ISO C11 and C17. For more information, see /std
(Specify language standard version).
The standard C runtime library is implemented by the Universal C runtime library (UCRT) in Windows. The UCRT also implements many POSIX and Microsoft-specific library extensions. The UCRT supports the ISO C11 and C17 C runtime library standards, with certain implementation-specific caveats. It doesn't support the full ISO C99 standard C runtime library. For more information, see compatibility in the Universal C runtime library documentation.
MSVC adds several Microsoft-specific keywords to C and C++. In the list in Keywords, the keywords that have two leading underscores are MSVC extensions.
Both the C++ compiler and C compiler support these kinds of non-standard casts:
The C compiler supports non-standard casts to produce l-values. For example:
char *p; (( int * ) p )++; // In C with /W4, both by default and under /Ze: // warning C4213: nonstandard extension used: cast on l-value // Under /TP or /Za: // error C2105: '++' needs l-value
Note
This extension is available in the C language only. You can use the following C standard form in C++ code to modify a pointer as if it's a pointer to a different type.
The preceding example could be rewritten as follows to conform to the C standard.
p = ( char * )(( int * )p + 1 );
Both the C and C++ compilers support non-standard casts of a function pointer to a data pointer. For example:
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc; /* No diagnostic at any level, whether compiled with default options or under /Za */
Both C and C++ compilers support 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 )
{ }
// In C with /W4, either by default or under /Ze:
// warning C4212: nonstandard extension used: function declaration used ellipsis
// In C with /W4, under /Za:
// warning C4028: formal parameter 2 different from declaration
// In C++, no diagnostic by default or under /Za.
The C compiler supports single-line comments, which are introduced by using two forward slash (//
) characters:
// This is a single-line comment.
Single-line comments are a C99 feature. They're unaffected by /Za
and cause no diagnostic at any level.
The C compiler supports the following scope-related features.
Redefinitions of
extern
items asstatic
:extern int clip(); static int clip() {} // In C and C++ with /W4, either by default or under /Ze: // warning C4211: nonstandard extension used: redefined extern to static // In C and C++ under /Za: // error C2375: 'clip': redefinition; different linkage
Use of benign typedef redefinitions within the same scope:
typedef int INT; typedef int INT; // No diagnostic at any level in C or C++
Function declarators have file scope:
void func1() { extern double func2( double ); // In C at /W4: warning C4210: nonstandard extension used: function given file scope } int main( void ) { func2( 4 ); // /Ze passes 4 as type double } // /Za passes 4 as type int
Use of block-scope variables that are initialized by using non-constant expressions:
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; }
The C compiler supports the following data declaration and definition features.
Mixed character and string constants in an initializer:
char arr[6] = {'a', 'b', "cde"}; // In C with /W4, either by default or under /Ze: // warning C4207: nonstandard extension used: extended initializer form // Under /Za: // error C2078: too many initializers
Bit fields that have base types other than
unsigned int
orsigned int
.Declarators that don't have a type:
x; // By default or under /Ze, /Za, /std:c11, and /std:c17, when /W4 is specified: // warning C4431: missing type specifier - int assumed. Note: C no longer supports default-int // warning C4218: nonstandard extension used: must specify at least a storage class or a type */ int main( void ) { x = 1; }
Unsized arrays as the last field in structures and unions:
struct zero { char *c; int zarray[]; // In C with /W4, either by default, under /Ze, /std:c11, and /std:c17: // warning C4200: nonstandard extension used: zero-sized array in struct/union // Under /Za: // error C2133: 'zarray': unknown size };
Unnamed (anonymous) structures:
struct { int i; char *s; }; // By default or under /Ze, /std:c11, and /std:c17, when /W4 is specified: // warning C4094: untagged 'struct' declared no symbols // Under /Za: // error C2059: syntax error: 'empty declaration'
Unnamed (anonymous) unions:
union { int i; float fl; }; // By default or under /Ze, /std:c11, and /std:c17, when /W4 is specified: // warning C4094: untagged 'union' declared no symbols // Under /Za: // error C2059: syntax error: 'empty declaration'
Both the x86 C++ compiler and C compiler support inline generation of the atan
, atan2
, cos
, exp
, log
, log10
, sin
, sqrt
, and tan
functions when /Oi
is specified. These intrinsics don't conform to the standard, because they don't set the errno
variable.
Under /Ze
, you have to include iso646.h
if you want to use text forms of the following operators:
Operator | Text form |
---|---|
&& |
and |
&= |
and_eq |
& |
bitand |
| |
bitor |
~ |
compl |
! |
not |
!= |
not_eq |
|| |
or |
|= |
or_eq |
^ |
xor |
^= |
xor_eq |
These text forms are available as C++ keywords under /Za
or when /permissive-
is specified or implied.
/Za
, /Ze
(Disable language extensions)
MSVC compiler options
MSVC compiler command-line syntax