Wichtige Änderungen im Visual C++ 2005-Compiler
Aktualisiert: November 2007
Dieses Thema behandelt die Änderungen im Verhalten von Visual C++ 2005, die dazu führen können, dass Code, der in früheren Versionen ordnungsgemäß funktionierte, entweder nicht mehr kompiliert werden kann oder zur Laufzeit ein anderes Verhalten aufweist.
Weitere Informationen über neue Features finden Sie unter Änderungen in Visual C++ 2005 und früheren Editionen, Änderungen in den Visual C++ 2005-Bibliotheken und unter Änderungen beim Compiler, bei der Sprache und bei den Tools von Visual C++ 2005.
Zeiger auf Member erfordern jetzt qualifizierten Namen und &
Code, der für frühere Compilerversionen geschrieben wurde, die nur den Methodennamen erforderten, verursacht jetzt Compilerfehler C3867 oder Compilerwarnung C4867. Diese Diagnose ist gemäß Standard-C++ erforderlich. Zum Erstellen eines Zeigers auf eine Memberfunktion müssen jetzt der Adressoperator (&) und der vollständig qualifizierte Methodenname verwendet werden. Wenn der &-Operator und der vollständig qualifizierte Name der Methode nicht verwendet werden müssen, kann dies aufgrund fehlender Klammern in Funktionsaufrufen zu logischen Fehlern im Code führen. Wenn der Funktionsname ohne Argumentliste verwendet wird, ergibt sich daraus ein Funktionszeiger, der in verschiedene Typen konvertiert werden kann. Dieser Code würde kompiliert zur Laufzeit zu unerwartetem Verhalten führen.Klasse muss für eine friend-Deklaration zugänglich sein
Visual C++-Compiler vor Visual C++ 2005 ermöglichten eine friend-Deklaration für eine Klasse, auf die im Gültigkeitsbereich der Klasse, die die Deklaration enthielt, nicht zugegriffen werden konnte. Jetzt gibt der Compiler Compilerfehler C2248 aus. Um diesen Fehler zu beheben, ändern Sie die Zugriffsebene der Klasse, die in der friend-Deklaration angegeben ist. Diese Änderung am Compiler wurde vorgenommen, um Konformität mit dem C++-Standard zu gewährleisten.__int asm 3 wird jetzt systemeigen kompiliert
Bei der Kompilierung mit /clr führte __asm int 3 nicht zur Generierung von systemeigenem Code. Der Compiler übersetzte die Anweisung in eine CLR-Unterbrechungsanweisung. In Visual C++ 2005 führt __asm int 3 jetzt zur Generierung von systemeigenem Code für die Funktion. Wenn eine Funktion einen Haltepunkt in Ihrem Code erzeugen und die Funktion in MSIL kompiliert werden soll, verwenden Sie __debugbreak. Weitere Informationen finden Sie unter __asm und unter /clr (Common Language Runtime-Kompilierung). Diese Änderung wurde vorgenommen, um gezielter zu bestimmen, wann systemeigener Code im Gegensatz zu verwaltetem Code generiert werden soll. Inlineassemblycode sollte systemeigenen Code generieren.Explizite Spezialisierung ist in einem Kopierkonstruktor/Kopierzuweisungsoperator nicht zulässig
Code, der eine explizite Vorlagenspezialisierung für einen Kopierkonstruktor oder Kopierzuweisungsoperator voraussetzt, generiert jetzt den Compilerfehler C2299. Standard-C++ verhindert dies. Diese Änderung wurde aus Konformitätsgründen vorgenommen, um die Codeportabilität zu verbessern.Nicht spezialisierte Klassenvorlage kann nicht als Vorlagenargument in einer Basisklassenliste verwendet werden
Die Verwendung des Klassennamens einer nicht spezialisierten Vorlage in der Basisklassenliste für eine Klassendefinition verursacht den Compilerfehler C3203. Es ist unzulässig, den Klassennamen einer nicht spezialisierten Vorlage als Vorlagenparameter in einer Basisklassenliste zu verwenden. Die Vorlagentypparameter müssen explizit zum Vorlagenklassennamen hinzugefügt werden, wenn dieser als Vorlagenparameter in einer Basisklassenliste verwendet wird. Diese Änderung wurde aus Konformitätsgründen vorgenommen, um die Codeportabilität zu verbessern.using-Deklarationen von geschachtelten Typen sind nicht mehr zulässig
Code, der eine using-Deklaration für einen geschachtelten Typ aufweist, generiert jetzt den Compilerfehler C2885. Um voll qualifizierte Verweise in geschachtelte Typen aufzulösen, fügen Sie den Typ in einen Namespace ein, oder erstellen Sie eine typedef. Diese Änderung wurde aus Konformitätsgründen vorgenommen, um die Codeportabilität zu verbessern.Compiler lässt für const_cast keine Abwärtskonvertierung unter /clr:oldSyntax zu
Vor Visual C++ 2005 ließ der Visual C++-Compiler für const_cast Operator eine Abwärtskonvertierung zu, wenn Quellcode kompiliert wurde, der Managed Extensions for C++-Syntax verwendete. Das Ausführen einer Abwärtskonvertierung mit const_cast führt jetzt zu Compilerfehler C2440. Um diesen Fehler zu beheben, verwenden Sie den richtigen Umwandlungsoperator. (Weitere Informationen finden Sie unter Casting Operators.) Diese Änderung wurde aus Konformitätsgründen vorgenommen.Compiler lässt Vorwärtsdeklaration einer verwalteten Enumeration nicht zu
Vor Visual C++ 2005 hat der Visual C++-Compiler Vorwärtsdeklarationen verwalteter Enumerationen zugelassen. Wenn jetzt bei der Kompilierung mit einer Form von /clr eine verwaltete Enumeration deklariert und nicht definiert wird, führt dies zu Compilerfehler C2599. Um diesen Fehler zu beheben, definieren Sie verwaltete Enumerationen immer bei der Deklaration. Diese Änderung wurde vorgenommen, da bei Vorwärtsdeklarationen von verwalteten Enumerationen nicht immer gewährleistet werden konnte, dass sie richtig funktionieren. Der Compiler ist nicht in der Lage, den zugrunde liegenden Typ der Enumeration richtig zu identifizieren. Außerdem lässt der C++-Standard keine Enumerationsdeklarationen zu.Compileroption /YX wurde entfernt
/YX generierte automatische Unterstützung für vorkompilierte Header. Sie wurde standardmäßig von der Entwicklungsumgebung verwendet. Wenn Sie /YX aus der Buildkonfiguration entfernen, ohne es zu ersetzen, läuft der Buildvorgang möglicherweise schneller ab. Abgesehen davon, dass /YX zu einem unerwarteten Verhalten führen kann, sollten Sie vorzugsweise /Yc (Datei der vorkompilierten Header erstellen) und /Yu (Vorkompilierte Headerdatei verwenden) verwenden. Auf diese Weise können Sie die Verwendung vorkompilierter Header besser steuern.Compileroption /Oa und Compileroption /Ow wurden entfernt
Die Compileroption /Ow und die Compileroption /Oa wurden entfernt, werden aber ohne Ausgabe einer Meldung ignoriert. Verwenden Sie den noalias-Modifizierer oder den restrict__declspec-Modifizierer, um anzugeben, wie der Compiler das Aliasing durchführt.Compileroption /Op wurde entfernt
Die Compileroption /Op wurde entfernt. Stattdessen sollte /fp (Festlegen des Gleitkommaverhaltens) verwendet werden.Compileroptionen /ML und /MLd wurden entfernt
Visual C++ unterstützt statisch gelinkte CRT-Bibliotheksunterstützung in einem Thread nicht mehr. Verwenden Sie stattdessen /MT und /MTd. Weitere Informationen finden Sie unter C Run-Time Libraries.Compileroptionen /G3, /G4, /G5, /G6, /G7 und /GB wurden entfernt
Der Compiler verwendet jetzt ein gemischtes Modell. Dieses versucht, eine Ausgabedatei zu erstellen, die für alle Architekturen ideal geeignet ist./Gf wurde entfernt
Verwenden Sie stattdessen /GF (Doppelte Zeichenfolgen beseitigen). /GF fügt Zeichenfolgen, für die ein Stringpooling durchgeführt wurde, in einen schreibgeschützten Abschnitt ein, was sicherer ist als das Einfügen in einen beschreibbaren Abschnitt mit /Gf./clr ist nicht mit /MT kompatibel
Es gibt keine Unterstützung in der C-Laufzeitbibliothek für eine statische Verknüpfung mit einer verwalteten Anwendung. Alle verwalteten Anwendungen müssen dynamisch verknüpft werden (/MD). Weitere Informationen über Einschränkungen bei der Verwendung von /clr finden Sie unter Einschränkungen für "/clr"./GS ist jetzt standardmäßig aktiviert
Die Pufferüberlaufprüfung ist jetzt standardmäßig aktiviert. Sie können die Pufferüberlaufprüfung mit /GS- deaktivieren. Weitere Informationen finden Sie unter /GS (Puffer-Sicherheitsüberprüfung)./Zc:wchar_t ist jetzt standardmäßig aktiviert
Dies entspricht dem C++-Standardverhalten: Einer wchar_t-Variablen wird standardmäßig der integrierte Typ zugewiesen, und nicht der Typ short unsigned int. Diese Änderung führt zur Aufhebung der Binärkompatibilität, wenn in den Clientcode Bibliotheken eingebunden werden, die ohne Angabe von /Zc:wchar_t kompiliert wurden (LNK2019). Verwenden Sie in diesem Fall /Zc:wchar_t-, um das alte, nicht dem Standard entsprechende Verhalten wiederherzustellen. Diese Änderung wurde eingeführt, um standardmäßig konformen Code zu erstellen.Weitere Informationen finden Sie unter /Zc:wchar_t (wchar_t ist der systemeigene Typ).
/Zc:forScope ist jetzt standardmäßig aktiviert
Dies entspricht dem C++-Standardverhalten. Code, der voraussetzt, dass eine Variable, die in einer for-Schleife deklariert wurde, außerhalb des Gültigkeitsbereichs der for-Schleife verwendet werden kann, wird jetzt nicht mehr kompiliert. Verwenden Sie /Zc:forScope-, um das alte, nicht dem Standard entsprechende Verhalten wiederherzustellen. Diese Änderung wurde eingeführt, um standardmäßig konformen Code zu erstellen.Weitere Informationen finden Sie unter /Zc:forScope (Übereinstimmung in for-Schleifenbereich erzwingen).
Erzwingen der Parameterprüfung für Visual C++-Attribute
Code, der benannte Attribute an einen Attributkonstruktor in Anführungszeichen übergibt, wenn dieser nicht den Typ string hat, bzw. ohne Anführungszeichen, wenn dieser den Typ string hat, generiert jetzt den Compilerfehler C2065 bzw. die Compilerwarnung (Stufe 1) C4581. Früher wurden alle Compilerattribute als Zeichenfolgen interpretiert, und der Compiler fügte bei Bedarf fehlende Anführungszeichen ein. Die Attributunterstützung wurde durch eine zusätzliche Validierung der Parameterprüfung verbessert. Dies verhindert, dass die Übergabe falscher Argumente an einen Attributkonstruktor zu einem unerwarteten Verhalten führt.In dieser Version ist keine Mehrfachbyte-Zeichenfolge (MBCS) in einem Argument für ein Attribut zulässig, das eine implizite Zeichenfolge als Argument annimmt, selbst wenn die Zeichenfolge in Anführungszeichen gesetzt wird (dies kann zu einer beschädigten IDL-Datei führen). Das Problem lässt sich folgendermaßen umgehen:
#define ARG string_with_MBCS_chars [helpstring(ARG)]
Compiler erfordert jetzt gleiche Vorlagenspezifikation für mehrere Deklarationen des gleichen Typs
Wenn Sie eine Vorwärtsdeklaration eines Typs haben, damit Sie z. B. friends für diesen Typ erstellen können, muss die Vorlagenspezifikation des Typs in allen Deklarationen für den Typ gleich sein. Andernfalls gibt der Compiler Compilerfehler C2990 aus.uuid-Attribut kann nicht mehr auf verwaltete Typen abzielen
Das uuid (C++ Attributes)-Attribut war für ein benutzerdefiniertes Attribut mit Managed Extensions for C++ zulässig, generiert aber nun Compilerfehler C3451. Stattdessen sollte GuidAttribute verwendet werden.Syntaxänderung für die Übergabe von verwalteten Arrays an benutzerdefinierte Attribute
Der Typ des Arrays wird nicht mehr aus der aggregierten Initialisierungsliste abgeleitet. Es ist nun erforderlich, sowohl den Arraytyp als auch die Initialisiererliste anzugeben. Die alte Syntax führt jetzt zu Compilerfehler C3104. Diese Änderung war erforderlich, weil der Compiler den Typ des Arrays nicht immer richtig aus der aggregierten Initialisierungsliste ableiten konnte.Compiler fügt nicht int als Standardtyp in Deklarationen ein
In Code, in dem in einer Deklaration kein Typ angegeben wird, wird nicht mehr standardmäßig int verwendet. Der Compiler generiert Compilerwarnung C4430 oder Compilerwarnung (Stufe 4) C4431. Der C++-Standard unterstützt die Verwendung von int als Standard nicht. Mit dieser Änderung wird sichergestellt, dass Sie den Typ erhalten, der wirklich gewünscht wird.dynamic_cast hat Konformität mit dem C++-Standard verbessert
Die C-Laufzeitbibliothek führt nun eine dynamic_cast-Laufzeitüberprüfung durch, um sicherzustellen, dass der Typ des umgewandelten Ausdrucks zur Kompilierzeit auf ein öffentliches Basisklassen-Unterobjekt entweder vom umgewandelten Zieltyp (für Abwärtskonvertierung) oder vom am meisten abgeleiteten Objekttyp (für die übergreifende Konvertierung) verweist. Weitere Informationen finden Sie unter Wichtige Änderungen in dynamic_cast.Ein R-Wert darf nicht an einen nicht konstanten Verweis gebunden werden.
Ein R-Wert darf nicht an einen nicht konstanten Verweis gebunden werden. In früheren Versionen von Visual C++ besteht die Möglichkeit, einen R-Wert an einen nicht konstanten Verweis in einer direkten Initialisierung zu binden. Dieser Code generiert jetzt Compilerwarnung (Stufe 1) C4350.Für Werttypen wird kein Standardkonstruktor ausgegeben, was zur Ausführung von Typinitialisierern an verschiedenen Punkten führen kann
Vor Visual C++ 2005 wurden statische Konstruktoren (Typeninitialisierer) in Werttypen ausgeführt, wenn eine Instanz des Werttyps erstellt wurde. Um die Ausführung von statischen Konstruktoren zu gewährleisten, greifen Sie auf einen statischen Datenmember zu, oder (nur /clr:oldSyntax) definieren Sie einen Instanzenkonstruktor. Für Werttypen wurde kein Standardkonstruktor bereitgestellt, weil die Common Language Runtime nicht garantiert, dass sie immer einen Standardkonstruktor aufruft. Wenn kein Standardkonstruktor für Werttypen bereitgestellt wird, wird außerdem die Leistung verbessert.Geschachtelte Werttypen sind jetzt in überprüfbaren (/clr:safe)-Kontexten schreibgeschützt
Die Common Language Runtime ermöglicht das Ändern eines geschachtelten Werttyps nicht mehr, wenn eine überprüfbare Assembly kompiliert wird. Der Compiler gibt jetzt Compilerwarnung C4972 aus, wenn dies erkannt wird.C4792 wird nur ausgegeben, wenn Sie den Wert des zugrunde liegenden Wertobjekts über das geschachtelte Wertobjekt ändern. Der Fehler tritt nicht auf, wenn Sie eine Kopie des Wertobjekts ändern (z. B. ein geschachteltes Objekt ändern).
Systemeigene Typen sind standardmäßig außerhalb der Assembly privat
Systemeigene Typen sind jetzt außerhalb der Assembly standardmäßig nicht sichtbar. Weitere Informationen über Typsichtbarkeit außerhalb der Assembly finden Sie unter Type Visibility. Anlass für diese Änderung waren in erster Linie die Anforderungen von Entwicklern, die andere, nicht zwischen Groß- und Kleinschreibung unterscheidende Sprachen verwenden, wenn sie auf Metadaten verweisen, die in Visual C++ erstellt wurden./clr akzeptiert jetzt neue CLR-Syntax für Visual C++
Vor Visual C++ 2005 kompilierte /clr Managed Extensions for C++-Syntax. /clr kompiliert jetzt die neue CLR-Syntax, und ./clr:oldSyntax kompiliert Managed Extensions for C++-Syntax. Weitere Informationen zu /clr finden Sie unter /clr (Common Language Runtime-Kompilierung). Weitere Informationen über die neue Syntax finden Sie unter Language Features for Targeting the CLR./clr kompiliert nicht mehr C-Quellcodedateien
Vor Visual C++ 2005 konnten Sie C-Quellcodedateien mit /clr kompilieren. Dies führt aber jetzt zu Befehlszeilenfehler D8045. Um diesen Fehler zu beheben, ändern Sie die Dateierweiterung in .cpp oder .cxx, oder kompilieren Sie mit /TP oder /Tp. Weitere Informationen finden Sie unter /Tc, /Tp, /TC, /TP (Typ der Quelldatei angeben).MSIL-Änderungen beim Testen auf Gleichheit
Weitere Informationen finden Sie unter Gewusst wie: Test auf Gleichheit.