インテル® C++ コンパイラー 15.0 ユーザー・リファレンス・ガイド
インテル® C++ コンパイラーは、Microsoft* Visual C++* コンパイラーと互換性はありますが、相違点もいくつかあり、正常にコンパイルできない場合があります。また、一部のソースファイルについては、インテル® C++ コンパイラーで互換性のないコードが生成されることがあります。ほとんどの場合は、ソースファイルを修正すればインテル® C++ コンパイラーでも Microsoft* Visual C++* コンパイラーでも正常にコンパイルできます。次に、この両者の相違点について説明します。
インテル® C++ コンパイラーと Microsoft* Visual C++* コンパイラーでは、#include 宣言子の中で使用するプリプロセッサー・マクロの展開方式が異なります。 例えば、あるマクロをトークン連結演算子を使用している別のマクロにパラメーターとして渡すコードについて考えてみます。この場合、パラメーターとして使用されているマクロは、連結前には展開されません。次のコードを用いて具体的に説明します。
#define D var #define Decl(d) int my ## d; Decl(D)
どちらのコンパイラーでも、上のソースコードを前処理すると次のコードを生成します。
int myD;
似たようなマクロが #include 宣言子の中で使用されていれば、インテル® C++ コンパイラーの動作は上の例と同じになります。 しかし、Microsoft* Visual C++* コンパイラーでは、その #include 宣言子の全体について余分に前処理が行われ、実行結果は異なります。 次の例で、D マクロと F マクロは #include 宣言子の中で使用していると、インテル® C++ コンパイラーでは展開されません。
#define D sys #define F stat.h #define INC(d,f) < ## d ## / ## f ## > #include INC(D,F)
コンパイラーによる解釈の例 |
---|
// インテル® C++ コンパイラー #include <D/F> |
// Visual C++* コンパイラー #include <sys/stat.h> |
インテル® C++ コンパイラーの場合は、D/F という名前のファイルが見つからないと、このコードに対してエラーを発行します。 Microsoft* Visual C++* コンパイラーの場合は、D マクロと F マクロを展開するので、このコードでも問題ありません。 コードを次のようにすれば、インテル® C++ コンパイラーでも Microsoft* Visual C++* コンパイラーでも問題なく処理でき、結果も同じになります。
#define D sys #define F stat.h #define CAT5(a,b,c,d,e) a ## b ## c ## d ## e #define INC(d,f) CAT5(<,d,/,f,>) #include INC(D,F)
インテル® C++ コンパイラーと Microsoft* Visual C++* コンパイラーでは、左シフト演算の評価方法が異なる場合があります。これは、左右のオペランドのサイズをビット単位で比較したときに、右辺のオペランド (つまりシフト桁数) のサイズが左辺のオペランドのサイズ以上の場合です。ANSI C 標準規格では、このような左シフト演算の動作は不定になっています。つまり、この演算の動作は予測できません。両コンパイラーで異なる結果が出るのは、このシフト演算の左右のオペランドが定数の場合だけです。次の例は、インテル® C++ コンパイラーと Microsoft* Visual C++* コンパイラーでの違いについて示したものです。
int x; int y = 1; // y を 1 に設定する void func() { x = 1 << 32; // インテル® C++ コンパイラーは x を 1 に設定するコードを生成する // Visual C++* コンパイラーは x を 0 に設定するコードを生成する y = y << 32; // インテル® C++ コンパイラーは y を 1 に設定するコードを生成する // Visual C++* コンパイラーは y を 0 に設定するコードを生成する }
IA-32 アーキテクチャーを対象にコンパイルする場合、goto 文のインライン・アセンブリー・ターゲット・ラベルは大文字と小文字が区別されます。 Microsoft* Visual C++* コンパイラーは、このようなラベルを扱うときに大文字と小文字を区別しません。例えば、次のコードをコンパイルするとインテル® C++ コンパイラーからはエラーが発行されます。
int func(int x) { goto LAB2; // エラー: 定義されていないラベル "LAB2" が参照されている __asm lab2: mov x, 1 return x; }
しかし、Microsoft* Visual C++* コンパイラーではこのコードを問題なく処理できます。インテル® C++ コンパイラーを使用する際には、インライン・アセンブリーの中で定義しているラベルを goto 文で参照する場合、そのラベル参照とラベル定義について、名前の大文字と小文字の違いも一致させてください。