インテル® C++ コンパイラー 19.1 デベロッパー・ガイドおよびリファレンス
インテル® C++ コンパイラーは、Microsoft* Visual C++* コンパイラーと互換性はありますが、相違点もいくつかあり、正常にコンパイルできない場合があります。また、一部のソースファイルについては、インテル® C++ コンパイラーで互換性のないコードが生成されることがあります。ほとんどの場合は、ソースファイルを修正すればインテル® C++ コンパイラーでも Microsoft* Visual C++* コンパイラーでも正常にコンパイルできます。次に、この両者の相違点について説明します。
インテル® 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 文で参照する場合、そのラベル参照とラベル定義について、名前の大文字と小文字の違いも一致させてください。
Microsoft* コンパイラーは dllimport 関数をインライン展開しませんが、インテル® コンパイラーは、dllimport 関数のインライン展開を試みます。そのため、dllimport ルーチン内で使用される呼び出しと変数がリンク時に 利用できなければなりません。そうでないと、シンボルが未解決になります。
次の例には、header.h と bug.cpp の 2 つのファイルが含まれます。
#ifndef _HEADER_H
#define _HEADER_H
namespace Foo_NS {
class Foo2 {
public:
Foo2(){};
~Foo2();
static int test(int m_i);
};
}
#endif
#include "header.h"
struct Foo2 {
static void test();
};
struct __declspec(dllimport) Foo
{
void getI() { Foo2::test(); };
};
struct C {
virtual void test();
};
void C::test() { Foo* p; p->getI(); }
int main() {
return 0;
}