コンパイラ エラー C2440
更新 : 2007 年 11 月
エラー メッセージ
'変換' : 'type1' から 'type2' に変換できません。
'type1' から 'type2' にキャストできません。
C2440 は、C++ 標準ライブラリで行われた準拠作業および更新作業の結果として発生することがあります。詳細については、標準 C++ ライブラリの変更点 : Visual C++ .NET 2003 および「Visual C++ のバージョン間のライブラリの変更点」を参照してください。
使用例
C2440 は、メンバへのポインタを void* に変換しようとして発生することもあります。次の例では C2440 エラーが生成されます。
// C2440.cpp
class B {
public:
void f(){;}
typedef void (B::*pf)();
void f2(pf pf) {
(this->*pf)();
void* pp = (void*)pf; // C2440
}
void f3() {
f2(f);
}
};
次の例の 15 行目と 16 行目の C2440 エラーには、Incompatible calling conventions for UDT return value というメッセージが表示されます。UDT とは、クラス、構造体、共用体などのユーザー定義型です。このような型で非互換性によるエラーが発生するのは、事前宣言の戻り値の型で指定された UDT の呼び出し規約が UDT の実際の呼び出し規約と競合する場合や、関数ポインタが関連する場合です。
この例では、最初に、構造体およびその構造体を返す関数の事前宣言があります。コンパイラでは、この構造体が C++ 呼び出し規約を使用すると仮定します。次に、構造体の定義があります。既定では、この定義は C 呼び出し規約を使用します。コンパイラでは、構造体全体の読み込みが完了するまでは、その構造体の呼び出し規約がわからないため、get_c2 の戻り値の型での構造体の呼び出し規約も C++ であると仮定します。
構造体の後には構造体を返す別の関数宣言が続きますが、この時点では、コンパイラは構造体の呼び出し規約が C++ であることを認識しています。同様に、構造体を返す関数ポインタは構造体定義の後に定義されているため、コンパイラはその構造体が C++ 呼び出し規約を使用することを認識します。
互換性のない 2 つの呼び出し規約が原因で発生する C2440 エラーを解決するには、UDT の定義の後にその UDT を返す関数を宣言します。
// C2440b.cpp
struct MyStruct;
MyStruct get_c1();
struct MyStruct {
int i;
static MyStruct get_C2();
};
MyStruct get_C3();
typedef MyStruct (*FC)();
FC fc1 = &get_c1; // C2440, line 15
FC fc2 = &MyStruct::get_C2; // C2440, line 16
FC fc3 = &get_C3;
class CMyClass {
public:
explicit CMyClass( int iBar)
throw() {
}
static CMyClass get_c2();
};
int main() {
CMyClass myclass = 2; // C2440
// try one of the following
// CMyClass myclass(2);
// CMyClass myclass = (CMyClass)2;
int *i;
float j;
j = (float)i; // C2440, cannot cast from pointer to int to float
}
C2440 は、内部ポインタに 0 を割り当てた場合にも発生することがあります。
// C2440c.cpp
// compile with: /clr
int main() {
array<int>^ arr = gcnew array<int>(100);
interior_ptr<int> ipi = &arr[0];
ipi = 0; // C2440
ipi = nullptr; // OK
}
C2440 は、ユーザー定義の規約の使用方法が間違っている場合にも発生することがあります。ユーザー定義の規約の詳細については、「User-Defined Conversions」を参照してください。次の例では C2440 エラーが生成されます。
// C2440d.cpp
// compile with: /clr
value struct MyDouble {
double d;
// convert MyDouble to Int32
static explicit operator System::Int32 ( MyDouble val ) {
return (int)val.d;
}
};
int main() {
MyDouble d;
int i;
i = d; // C2440
// Uncomment the following line to resolve.
// i = static_cast<int>(d);
}
C2440 は、型が Array である Visual C++ 配列のインスタンスを作成しようとした場合にも発生することがあります。詳細については、「array」を参照してください。次の例では C2440 エラーが生成されます。
// C2440e.cpp
// compile with: /clr
using namespace System;
int main() {
array<int>^ intArray = Array::CreateInstance(__typeof(int), 1); // C2440
// try the following line instead
// array<int>^ intArray = safe_cast<array<int> ^>(Array::CreateInstance(__typeof(int), 1));
}
C2440 は、属性機能の変更が原因で発生することもあります。次の例では C2440 エラーが生成されます。
// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ]; // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];
このエラーは、Visual C++ 2005 で行ったコンパイラ準拠作業の結果として生成されることもあります。Visual C++ コンパイラは、/clr プログラミングを使用するソース コードをコンパイルするときに const_cast Operator のダウン キャストを許可しなくなりました。
この C2440 を解決するには、正しいキャスト演算子を使用します。詳細については、「Casting Operators」を参照してください。詳細については、「Visual C++ 2005 コンパイラの互換性に影響する変更点」を参照してください。
次の例では C2440 エラーが生成されます。
// c2440g.cpp
// compile with: /clr
ref class Base {};
ref class Derived : public Base {};
int main() {
Derived ^d = gcnew Derived;
Base ^b = d;
d = const_cast<Derived^>(b); // C2440
d = dynamic_cast<Derived^>(b); // OK
}
C2440 は /clr:oldSyntax の使用でも生成されることがあります。次の例では C2440 エラーが生成されます。
// c2440h.cpp
// compile with: /clr:oldSyntax
__gc class Base {};
__gc class Derived : public Base {};
int main() {
Derived *d = new Derived;
Base *b = d;
d = const_cast<Derived*>(b); // C2440
d = dynamic_cast<Derived*>(b); // OK
}