Nach sechsmonatiger Entwicklungszeit wurde die Version 18.1.0 des LLVM-Projekts veröffentlicht – ein mit GCC kompatibles Toolset (Compiler, Optimierer und Codegeneratoren), das Programme in Zwischen-Bitcode RISC-ähnlicher virtueller Instruktionen übersetzt (eine Niedrig-Level-Virtual Machine mit einem mehrstufigen Optimierungssystem). Der erzeugte Pseudocode kann mittels eines JIT-Compilers während der Programmausführung direkt in Maschineninstruktionen umgewandelt werden.
Seit dem Branch 18.x folgt das Projekt einem neuen Schema zur Versionierung. Analog zu den Projekten GCC und GDB wird die Null-Ausgabe („N.0“) nun während der Entwicklung verwendet, während die erste stabile Version die Nummer „N.1“ erhält. Diese Änderung ermöglicht es, Entwicklungs-Builds von der Hauptlinie (mainline) von Build-Versionen mit finalen Releases zu trennen. Zum Beispiel wurde für die aktuelle Veröffentlichung die Entwicklung unter Verwendung des instabilen Branches LLVM 18.0 durchgeführt, und das erste stabile Release wurde unter der Nummer 18.1.0 veröffentlicht. Zukünftig können bei Bedarf alle zwei Wochen Korrektur-Releases unter den Nummern 18.1.1, 18.1.2 usw. erstellt werden. Bei Änderungen in dem aktuellen Branch, die die ABI beeinträchtigen, wird das Update mit einer Änderung der zweiten Versionszahl (d.h. 18.2.0) formuliert.
Die Hauptverbesserungen in Clang 18:
- Änderungen in der C-Sprache:
- Strukturen, Unionen und Arrays mit dem Attribut „const“ können nun analog zu GCC als konstante Ausdrücke verwendet werden.
- Enumerationen (enum) werden jetzt in den TBAA-Metadaten (Type Based Alias Analysis) in ihrem ursprünglichen ganzzahligen Typ dargestellt, anstatt als „char“ behandelt zu werden.
- Die Unterstützung für das Attribut „counted_by“ wurde hinzugefügt, mit dem ein Feld in einer Struktur mit flexiblem Array angegeben werden kann, das die Anzahl der Elemente im flexiblen Array definiert. Dieses Attribut kann in clang verwendet werden, um die Effizienz der Grenzwertprüfungen zu erhöhen.
- Möglichkeiten, die im zukünftigen C-Standard C23 definiert sind:
- Die Unterstützung der Flags „-std=c23“ und „-std=gnu23“ sowie des Wertes „202311L“ für das Makro „__STDC_VERSION__“, das den C23-Standard und die GNU C23-Erweiterungen definiert, wurde hinzugefügt.
- Die Unterstützung des Ausdrucks „requires c23“ wurde hinzugefügt, um Module an die Unterstützung des C23-Standards zu binden.
- Die Unterstützung für die Typausgabe bei der Definition von Objekten wurde implementiert, was es ermöglicht, anstelle eines Typs die Bezeichnung „auto“ zu verwenden, um den Typ von Variablen basierend auf dem Typ des Ausdrucks für deren Initialisierung zu bestimmen. Zum Beispiel: „auto y = cos(x);“.
- Die Unterstützung für die Header-Datei mit Makros zur Überprüfung von ganzzahligen Berechnungen wurde hinzugefügt.
- Das Setzen von Labels an beliebigen Stellen innerhalb zusammengesetzter Ausdrücke wurde genehmigt.
- Beim Kompilieren im C23-Modus wurde die Unterstützung für Trigraphen, eine Sequenz aus drei ASCII-Zeichen, die als ein Zeichen behandelt wird, eingestellt. Zum Beispiel konnte die Sequenz «??=» anstelle von «#» verwendet werden. Mit dem Erscheinen von Unicode hat die Unterstützung für Trigraphen an Bedeutung verloren.
- Funktionen im Zusammenhang mit dem C++20-Standard: Es wurde eine experimentelle Möglichkeit implementiert, in Vorlagen zusätzliche Arten von Argumenten zu verwenden, die keine Typen sind, beispielsweise ist die Angabe von Fließkommawerten, Zeigern und Referenzen auf Teilobjekte zulässig.
- Funktionen im Zusammenhang mit dem C++23-Standard: Experimentelle Unterstützung für den Mechanismus «Deducing this» wurde hinzugefügt, der es ermöglicht, in der Vorlage Parameter mit dem Bezeichner «this» zu verwenden und einer Klassenfunktion die Kategorie des Ausdrucks (z. B. ob es sich um eine Konstante handelt) zu entlocken, für den diese Funktion aufgerufen wurde.
- Funktionen im Zusammenhang mit dem zukünftigen C++2c-Standard (C++26):
- Es wurde die Möglichkeit eingeführt, mehrere Platzhaltervariablen mit dem Namen „_“ in einem Sichtbereich zu verwenden, zum Beispiel sind jetzt folgende Konstruktionen korrekt: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // zuvor wurde eine Warnung im Modus -Wunused ausgegeben }
- Es wurde die Nutzung von Zeichenfolgenliteralen in Kontexten ermöglicht, in denen sie nicht zur Initialisierung von Zeichenarrays verwendet werden und nicht in den endgültigen Code eingehen, sondern nur während der Kompilierung für diagnostische Meldungen und Preprozessierung verwendet werden, beispielsweise als Parameter von Direktiven und Attributen wie _Pragma, asm, extern, static_assert, [[deprecated]] und [[nodiscard]].
- Die Durchführung impliziter Umwandlungen von Enumerationswerten in arithmetischen Berechnungen wurde als veraltet eingestuft. int main() { enum E1 { e }; enum E2 { f }; bool b = e
Quelle: opennet.ru
