Unterschiede zwischen C++-Compilern, die durch Clang erweitert wurden, und C++-Compilern der vorherigen Generation

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Durch Clang erweiterte C++-Compiler


Dieses Thema enthält einen Überblick über die Unterschiede zwischen C++-Compilern, die durch Clang erweitert wurden, und ihrem unmittelbaren Vorgänger, BCC32.

Befehlszeilenoptionen

Durch Clang erweiterte C++-Compiler verwenden einen beinahe vollkommen anderen Satz von Befehlszeilenoptionen und drücken mehrere Werte für dieselbe Option auf eine andere Art und Weise aus.

Strikterer C++-Compiler

Durch Clang erweiterte C++-Compiler sind mit den C++-Sprachstandards konformer als BCC32. Sie unterstützen C++11, sind aber strikter. Siehe Striktere C++-Compiler (Durch Clang erweiterte C++-Compiler)..

Warnungen und Fehlermeldungen

Zusätzlich zu den neuen, genaueren und detaillierteren Warnungen und Fehlermeldungen werden von C++-Compilern, die durch Clang erweitert wurden, Meldungen für von BCC32 erkannte Bedingungen auf eine andere Art formuliert.

Weitere Informationen finden Sie unter Fehler und Warnungen von C++-Compilern, die durch Clang erweitert wurden.

Vordefinierte Makros

Mit C++-Compilern, die durch Clang erweitert wurden, können Sie alle vordefinierten Makros direkt vom Präprozessor abrufen.

Makro RTLVersion

Die Konstante RTLVersion wird von C++-Compilern, die durch Clang erweitert wurden, nicht unterstützt. Stattdessen können Sie RTLVersionC verwenden.

Makro NO_STRICT

Das Typprüfungsschema NO_STRICT wird in C++-Compilern, die durch Clang erweitert wurden, nicht unterstützt. In vorhandenen Projekten, die die konditionale Definition NO_STRICT enthalten, müssen Sie diese entfernen.

Weitere Informationen und Anleitungen zum Entfernen von NO_STRICT finden Sie unter C++-Anwendungen verwenden eine strikte Typprüfung.

#include-Pfade und Suche

In Compilern, die durch Clang erweitert wurden, müssen Sie Header eventuell anders einbeziehen #include.

Durch Clang erweiterte C++-Compiler finden im Gegensatz zu BCC32 Header beispielsweise nicht, die mit halbabsoluten Pfaden angegeben sind. Angenommen "myOtherFile" befindet sich im Verzeichnis C:/myProjectsDir/myOtherApp, dann werden die folgenden Verweise in einer CPP-Datei von C++-Compilern, die durch Clang erweitert wurden, und BCC32 akzeptiert:

#include "c:/myProjectsDir/myApp/mySource.h" // Absolute path.
#include "../myApp/mySource.h" // Relative path.

Die folgende Anweisung produziert jedoch einen Fehler in C++-Compilern, die durch Clang erweitert wurden, wird aber von BCC32 akzeptiert:

#include "/myProjectsDir/myApp/mySource.h" // Semi-absolute path.

Durch Clang erweiterte C++-Compiler geben den folgenden Fehler aus:

[<compiler> Fatal Error] myOtherFile.cpp(27): '/myProject/myApp/mySource.h' file not found

Weitere Informationen finden Sie unter Durch Clang erweiterte C++-Compiler, #include-Pfade und Suche.

Vorcompilierte Header

Vorcompilierte Header arbeiten in C++-Compilern, die durch Clang erweitert wurden, im Vergleich zu BCC32 etwas anders. Jedes C++-Projekt darf nur einen vorcompilierten Header haben, und ein vorcompilierter Standard-Header (ProjektPCHn.h) wird für jedes neue C++-Projekt generiert.

Weitere Informationen finden Sie in den folgenden Themen:

Format für Objekt- und Bibliotheksdateien

  • BCC32 und die zugehörigen Tools verwenden in .obj- und .lib-Dateien OMF.
  • Durch Clang erweiterte C++-Compiler verwenden in .o- und .a-Dateien ELF.

Dieser Unterschied bedeutet beispielsweise, dass Sie bei der Migration von 32-Bit-Windows-Anwendungen die Verweise auf .lib- und .obj-Dateien in .a bzw. .o ändern müssen.

__property: Verbund- und verkettete Zuweisung

Durch Clang erweiterte C++-Compiler unterstützen die Verbundzuweisung von __property, BCC32 unterstützt dies nicht.

Die Objekte des Schlüsselworts __property entsprechen keinen Feldern oder Membern. Sie sollten in einfachen Zuweisungen verwendet werden.

Zwar lassen sowohl BCC32 als auch durch Clang erweiterte C++-Compiler von RAD Studio __property in Verbundzuweisungen wie der folgenden zu:

Form1->Caption += DateToStr(Now());

BCC32 ruft aber nur die Getter-, nicht die Setter-Methode auf. Deshalb sollten Sie derartige Konstrukte vermeiden, wenn Sie plattformübergreifende Anwendungen entwickeln.

Keiner dieser Compiler unterstützt die Verwendung von __property in verketteten Zuweisungen wie in:

Button2->Caption = Button1->Caption = DateToStr(Now()); // Error

Veraltete BCC32-Erweiterungen und -Schlüsselwörter

Compiler-Schlüsselworterweiterungen ohne Unterstrich oder mit einem einzelnen Unterstrich werden in C++-Compilern, die durch Clang erweitert wurden, entweder nicht unterstützt oder sind veraltet. Verwenden Sie die Versionen mit den doppelten Unterstrichen (diese werden auch in BCC32 unterstützt):

  • cdecl, _cdecl:    Verwenden Sie __cdecl.
  • pascal, _pascal:    Verwenden Sie __pascal.
  • _fastcall:    Verwenden Sie __fastcall (ist jetzt Microsoft-, nicht Borland-Stil).
  • _stdcall:    Verwenden Sie __stdcall.
  • _fortran, __fortran:    

Wird nicht unterstützt, obsolet.

Nicht unterstützte BCC32-Attribute

Siehe Workaround für C++11-Attribute (Durch Clang erweiterte C++-Compiler) (noreturn und final).

Unicode-Bezeichner werden nicht unterstützt

Unicode wird zwar in Literal-Strings und Dateinamen unterstützt, ist aber in Bezeichnern nicht zulässig.

Inline-Assembly

Durch Clang erweiterte C++-Compiler lassen Inline-Assembly unter folgenden Vorbehalten zu:

  • Assembly-Code darf nicht mit C++-Code vermischt werden.
  • Der Stack-Zeiger (RSP) darf nicht verändert werden.
  • Der Assembler muss die zeilenweise AT&T-Syntax verwenden, nicht die bekanntere Block-of-Intel-Syntax. Weitere Informationen finden Sie unter GCC-Inline-Assembly-HOWTO (EN).

Durch Clang erweiterte C++-Compiler unterstützen einen anderen Inline-Assembly-Stil als BCC32:

  • Unterschiedliche Assembly-Syntax:
    Die durch Clang erweiterten C++-Compiler unterstützen als Assembly-Syntax die zeilenweise AT&T-Syntax, nicht die bekanntere Block-of-Intel-Syntax.
  • Mögliche Probleme bei der Exception-Behandlung und dem Debuggen:
Die Exception-Behandlung der Compiler beinhaltet zusätzliche Beschränkungen für handgeschriebenen Code, der mit C++ vermischt wird. Sie können Funktionen, die vollständig in Assembly (mit einem separaten Assembler wie NASM oder MASM) geschrieben sind, in Ihre Programme einbinden. Es gibt jedoch inhärente Probleme (bei der Exception-Behandlung und dem Debuggen), die Sie kennen müssen, bevor Sie beginnen.
Die Gründe für diese Probleme bei Inline-Assembly können wie folgt zusammengefasst werden: pdata. Eine fehlende Unterstützung für Inline-Assembly ist ziemlich häufig; damit Exceptions (und das Debugging) funktionieren, muss der Code Datenstrukturen (pdata) generieren, die alle Funktionen und die Abwicklung beim Auslösen einer Exception beschreiben. Nach dem Einfügen von Inline-Assembly erkennt der Compiler keine genaueren Details (wie zusätzlichen von Inline-Assembly zugewiesenen Stack-Platz). Inline-Assembly (d. h., das Vermischen von Assembly- und C/C++-Code) macht es dem Compiler unmöglich, pdata-Strukturen korrekt zu generieren. Weitere Informationen zu pdata finden Sie unter http://msdn.microsoft.com/de-de/library/1eyas8tf.aspx.

Ein Codebeispiel, das die Verwendung von Inline-Assembly mit einem Compiler, der durch Clang erweitert wurde, zeigt, finden Sie unter Inline Assembly with BCC64 (C++) (EN).

Weitere Informationen über Assembly mit C++-Compilern, die durch Clang erweitert wurden, finden Sie unter:

Try-Blöcke können einige Exceptions nicht behandeln

Synchrone Exceptions sind Exceptions, die mit der Anweisung throw in Ihrem Programm oder in den von Ihrem Programm verwendeten Bibliotheken ausgelöst werden. Compilern ist bekannt, wann und wo diese Exceptions ausgelöst werden.
Asynchrone Exceptions sind Exceptions, die vom Betriebssystem stammen, und jederzeit ausgelöst werden können, wie Divisionen durch Null oder Zugriffsverletzungen.

Standard-C und -C++ sind nur für die Behandlung von synchronen Exceptions ausgelegt. Wenn Sie Ihre C++Builder-Anwendungen aber mit der RTL verknüpfen, erweitern Sie Ihre Anwendungen um die Fähigkeit, auch asynchrone Exceptions abzufangen.

Clang ist jedoch nur für synchrone Exceptions ausgelegt, und die Exception-Behandlung ohne Aufruf wird nicht unterstützt. Wenn in einem try-Block keine "throw"-Anweisungen und keine Aufrufe von Funktionen enthalten sind, die "throw"-Anweisungen enthalten könnten, ignoriert Clang alle catch und __finally-Blöcke, die diesem try-Block zugeordnet sind. Das heißt: Wenn ein try-Block keine synchrone Exception auslösen kann, können Sie auch keine asynchrone Exception in diesem try-Block abfangen.

Zum Beispiel:

float a = 1;
float b = 0;
try {
    try {
        a = a / b;  // The RTL throws an asynchronous exception (division by zero).
    }
    __finally {
        // Execution never reaches this point.
    }
}
catch (...) {
    // Execution never reaches this point.
}

Anstatt diese speziellen Exceptions abzufangen, die durch Clang erweiterte Compiler nicht behandeln können, sollten Sie einen der folgenden Schritte ausführen:

  • Verschieben Sie den Code, der eine asynchrone Exception auslösen könnte, in seine eigene Funktion, und rufen Sie diese Funktion aus Ihrem try-Block auf.
  • Versuchen Sie zu verhindern, dass diese Exceptions ausgelöst werden. Sie könnten beispielsweise den Wert von b vor dem Durchführen der Division prüfen.
Hinweis: Wenn diese asynchronen Exceptions nicht abgefangen werden, fängt die Standard-Exception-Behandlungsroutine des GUI-Frameworks der Anwendung sie ab, und die Anwendung generiert die Fehlermeldung Externe Exception EEFFACE.

Automatisierungseinheiten aus Office XP werden nicht unterstützt

Führen Sie ein Upgrade auf Office 2010-Automatisierungseinheiten durch, um die XP-Funktionen und mehr zu verwenden.

Siehe auch