Freigeben über


Compilerfehler C2440

Aktualisiert: November 2007

Fehlermeldung

'Konvertierung': Konvertierung von 'Typ1' in 'Typ2' nicht möglich
'conversion' : cannot convert from 'type1' to 'type2'

Der Compiler ist nicht in der Lage, 'type1' in 'type2' umzuwandeln.

C2440 kann infolge einer Konformitätsverbesserung und Aktualisierung der Standard-C++-Bibliothek auftreten. Weitere Informationen finden Sie unter Änderungen in der C++-Standardbibliothek: Visual C++ .NET 2003 und Bibliotheksänderungen in Visual C++-Versionen.

Beispiel

C2440 kann verursacht werden, wenn Sie versuchen, einen Memberzeiger in void* zu konvertieren. Im folgenden Beispiel wird C2440 generiert.

// 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);
   }
};

Die C2440-Fehler in den Zeilen 15 und 16 des folgenden Beispielcodes sind durch die Meldung Incompatible calling conventions for UDT return value gekennzeichnet. (Ein UDT (user-defined type) ist ein benutzerdefinierter Typ, z. B. eine Klasse, Struktur oder Union.) Diese Typen von Inkompatibilitätsfehlern treten auf, wenn die Aufrufkonvention eines UDTs, die im Rückgabetyp einer Vorwärtsdeklaration festgelegt wurde, Konflikte mit der aktuellen Aufrufkonvention des UDTs verursacht und zugleich ein Funktionszeiger betroffen ist.

Das Beispiel enthält zunächst Vorwärtsdeklarationen für eine Struktur und für eine Funktion, durch die die Struktur zurückgegeben wird. Der Compiler geht davon aus, dass die Struktur die C++-Aufrufkonvention verwendet. Darauf folgt die Strukturdefinition, die standardmäßig die C-Aufrufkonvention verwendet. Da der Compiler die Aufrufkonvention der Struktur nicht kennt, solange die Struktur nicht vollständig eingelesen ist, setzt er voraus, dass die Aufrufkonvention für die Struktur im Rückgabetyp von get_c2 ebenfalls C++ entspricht.

Auf die Struktur folgt eine weitere Funktionsdeklaration, durch die die Struktur zurückgegeben wird. Zu diesem Zeitpunkt weiß der Compiler jedoch bereits, dass die Struktur die C++-Aufrufkonvention verwendet. Entsprechend wird der Funktionszeiger, durch den die Struktur zurückgegeben wird, erst nach der Struktur definiert. Daher ist dem Compiler bekannt, dass die Struktur die C++-Aufrufkonvention verwendet.

Um den durch inkompatible Aufrufkonventionen hervorgerufenen Fehler C2440 zu beheben, sollten Sie Funktionen deklarieren, die einen UDT nach der UDT-Definition zurückgeben.

// 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 kann auch auftreten, wenn Sie einem inneren Zeiger 0 (null) zuweisen:

// 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 kann auch bei nicht ordnungsgemäßer Verwendung einer benutzerdefinierten Konvertierung auftreten. Weitere Informationen zu benutzerdefinierten Konvertierungen finden Sie unter User-Defined Conversions. Im folgenden Beispiel wird C2440 generiert.

// 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 kann auch bei dem Versuch auftreten, eine Instanz eines Visual C++-Arrays vom Typ Array zu erstellen. Weitere Informationen finden Sie unter array (Visual C++). Im folgenden Beispiel wird C2440 generiert.

// 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 kann auch aufgrund von Änderungen im Attributfeature auftreten. Im folgenden Beispiel wird C2440 generiert.

// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ];   // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];

Dieser Fehler kann auch infolge einer Verbesserung der Compilerkonformität für Visual C++ 2005 ausgegeben werden: Der Visual C++-Compiler unterstützt beim Kompilieren von Quellcode mit /clr-Programmierung keine Abwärtskonvertierung durch den const_cast Operator mehr.

Um diese Ursache für C2440 zu vermeiden, verwenden Sie den richtigen Umwandlungsoperator. (Weitere Informationen finden Sie unter Casting Operators.) Weitere Informationen finden Sie unter Wichtige Änderungen im Visual C++ 2005-Compiler.

Im folgenden Beispiel wird C2440 generiert.

// 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 kann auch mit /clr:oldSyntax generiert werden. Im folgenden Beispiel wird C2440 generiert.

// 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
}