Compiler Error C2440
Error Message
'conversion' : cannot convert from 'type1' to 'type2'
The compiler cannot cast from 'type1' to 'type2'.
C2440 can occur as the result of conformance and update work that was done in the Standard C++ Library. See Standard C++ Library Changes: Visual C++ .NET 2003 and Library Changes in Visual C++ Releases for more information.
Example
C2440 can be caused if you attempt to convert a pointer to member to void*. The following sample generates 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);
}
};
The C2440 errors on lines 15 and 16 of the next sample will be qualified with the Incompatible calling conventions for UDT return value
message. (A UDT is a user-defined type, such as a class, struct, or union.) These types of incompatibility errors are caused when the calling convention of a UDT specified in the return type of a forward declaration conflicts with the actual calling convention of the UDT and when a function pointer is involved.
In the example, we first have forward declarations for a struct and for a function that returns the struct; the compiler assumes that the struct uses the C++ calling convention. Then we have the struct definition, which, by default, uses the C calling convention. Since the compiler does not know the calling convention of the struct until it finishes reading the entire struct, the calling convention for the struct in the return type of get_c2 is also assumed to be C++.
The struct is followed by another function declaration that returns the struct, but at this point, the compiler knows that the struct's calling convention is C++. Similarly, the function pointer, which returns the struct, is defined after the struct definition so the compiler knows that the struct uses the C++ calling convention.
To resolve C2440 because of incompatible calling conventions, declare functions that return a UDT after the UDT definition.
// 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 can also occur if you assign zero to an interior pointer:
// 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 can also occur for an incorrect use of a user-defined conversion. For more information on user-defined conversions, see User-Defined Conversions). The following sample generates 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 can also occur if you try to create an instance of a Visual C++ array whose type is a Array. For more information, see array. The following sample generates 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 can also occur because of changes in the attributes feature. The following sample generates C2440.
// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ]; // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];
This error can also be generated as a result of compiler conformance work that was done for Visual C++ 2005: the Visual C++ compiler no longer allows the const_cast Operator to down cast when compiling source code that uses /clr programming.
To resolve this C2440, use the correct cast operator (for more information, see Casting Operators). See Breaking Changes in the Visual C++ 2005 Compiler for more information.
The following sample generates 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 can also be generated using /clr:oldSyntax. The following sample generates 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
}