Microsoft C/C++ の拡張機能
Visual C++ は ANSI 規格で C、および C++ 標準を次のように拡張します。
Keywords
複数のキーワードが追加されます。C++ のキーワードの一覧で、のキーワードは 2 個の先頭にアンダースコア Visual C++ の拡張です。
静的な定数型の整数 (または列挙) メンバーのクラス外定義
標準 (/Za) の下に、次に示すように、データ メンバーのクラス定義を作成する必要があります:
class CMyClass {
static const int max = 5;
int m_array[max];
}
...
const int CMyClass::max; // out of class definition
/Ze では、静的で定数型の整数および列挙のデータ メンバーのクラス外定義は省略可能です。静的で定数だけクラスの初期化子を持つことができますが、および列挙型 (Enum) ; 初期化式は、定数式である必要があります。
のクラス定義がヘッダー ファイルに指定され、そのヘッダー ファイルを複数のソース ファイルに含まれている場合にエラーを回避するには、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 コンパイラでは、2 種類のスラッシュ (//) 文字で始まる単一行コメントをサポートしています:
// 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整数型以外基本型がある Bit のフィールド。
ストレージ クラスまたは型がない宣言子:
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 固有の仕様→atan、atan2、cos、exp、log、log10、sin、sqrt、および tan の各関数の← x86 固有の仕様インライン生成をサポートします。これらの関数のインライン形式では errno 変数が設定されないため、C プログラムでは ANSI C に準拠しなくなります。
const ポインター パラメーターの参照を予測している関数に非 const ポインター パラメーターを渡す
これは 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)
&= (and_eq)
& (bitand)
| (bitor)
~ (compl)
!(not)
!= (not_eq)
|| (or)
|= (or_eq)
^ (xor)
^= (xor_eq)
リテラル文字列のアドレスの型は const char const char [] で、const char (*) [] ではありません。
/Za で char const (*)[4] を出力し、/Ze で char const [4] を出力する例を次に示します。
#include <stdio.h>
#include <typeinfo>
int main()
{
printf_s("%s\n", typeid(&"abc").name());
}