Microsoft C 和 C++ 扩展
Visual C++ 如下扩展 ANSI C 和 ANSI C++ 标准。
关键字
多个关键字添加到中。在 C++关键字的列表,具有的关键字两个前导下划线是 Visual C++ 扩展。
static const 整型(或枚举)成员的类外定义
根据该条件 (/Za),则必须进行数据成员的一个外部类的定义,如下所示:
class CMyClass {
static const int max = 5;
int m_array[max];
}
...
const int CMyClass::max; // out of class definition
在 /Ze 下,类外定义对于静态、常量整型和常量枚举数据成员是可选的。是静态的整型和仅枚举和常量可以在选件类的初始值设定项;该初始化的表达式必须是常数表达式。
若要避免错误,当一个外部类的定义。标头文件时提供,并且标头文件在源文件中,请使用 selectany。例如:
__declspec(selectany) const int CMyClass::max = 5;
强制转换
编译器支持这些非 ANSI 转换:
非 ANSI 导致左值的转换。例如:
char *p; (( int * ) p )++;
说明
此扩展可在仅限于 C 语言。在 C++ 代码中使用下列 ANSI C 标准窗体修改指针,就象它指向不同的类型。
前面的示例看复盖符合 ANSI C 标准。
p = ( char * )(( int * )p + 1 );
非 ANSI 函数指针的转换为数据的指针。例如:
int ( * pfunc ) (); int *pdata; pdata = ( int * ) pfunc;
在转换到数据指针之前,若要执行相同的转换并维护 ANSI 兼容性,您可以将函数指针到 uintptr_t :
pdata = ( int * ) (uintptr_t) pfunc;
变长参数列表
编译器支持指定参数数目可变的函数声明,后跟提供了一种类型的函数定义:
void myfunc( int x, ... );
void myfunc( int x, char * c )
{ }
单行注释
C 编译器支持单行注释,通过使用两个正斜杠 (/) 字符,引入:
// This is a single-line comment.
范围
C 编译器支持以下大小相关的功能。
将 extern 项重定义为 static:
extern int clip(); static int clip() {}
在同一范围内使用良性的 typedef 重定义:
typedef int INT; typedef int INT;
函数声明符具有文件范围:
void func1() { extern int func2( double ); } int main( void ) { func2( 4 ); // /Ze passes 4 as type double } // /Za passes 4 as type int
如何使用,用非常数表达式初始化的块范围变量的使用:
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; }
数据声明和定义
C 编译器支持以下数据声明和定义功能。
初始值设定项中的混合字符和字符串常数:
char arr[5] = {'a', 'b', "cde"};
除了 unsigned int 或 signed int外,还有基类型的位域。
没有存储类或类型的声明:
x; int main( void ) { x = 1; }
未确定大小的数组,作为结构和联合中的最后字段:
struct zero { char *c; int zarray[]; };
未命名(匿名)结构:
struct { int i; char *s; };
未命名(匿名)联合:
union { int i; float fl; };
未命名成员:
struct s { unsigned int flag : 1; unsigned int : 31; }
内部浮点函数
当指定 /Oi 时,编译器支持以内联方式生成 x86 Specific > 和 END x86 Specific 的 atan、atan2、cos、exp、log、log10、sin、sqrt 和 tan 函数。对于 C,当使用这些内部函数时会丢失 ANSI 一致性,因为它们没有设置 errno 变量。
将非常数指针参数传递给需要常数指针参数的引用的函数
这是对 C++ 的扩展。此代码将编译 /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
在 /Ze 下,如果希望使用下列运算符的文本形式,必须包含 iso646.h:
&&(与)
&= (and_eq)
& (bitand)
| (bitor)
~ (compl)
!(not)
!= (not_eq)
|| (or)
|= (or_eq)
^ (xor)
^= (xor_eq)
字符串写入地址的类型为 const char [],不是常数字符 (*) []
下面的示例在 /Za 下输出 char const (*)[4],但在 /Ze 下输出 char const [4]。
#include <stdio.h>
#include <typeinfo>
int main()
{
printf_s("%s\n", typeid(&"abc").name());
}