Generische Auswahl (seit C11)
Bietet eine Möglichkeit, zur Compile-Zeit einen von mehreren Ausdrücken basierend auf dem Typ eines Kontrollausdrucks auszuwählen
Inhalt |
[bearbeiten] Syntax
_Generic ( Kontrollausdruck , Assoziationsliste ) |
(seit C11) | ||||||||
wobei Assoziationsliste eine kommagetrennte Liste von Assoziationen ist, von denen jede die folgende Syntax hat:
Typname : Ausdruck |
|||||||||
default : Ausdruck |
|||||||||
wobei
| Typname | - | Jeder vollständige Objekttyp, der nicht variablenmodifiziert ist (d. h. kein VLA oder Zeiger auf VLA). |
| Kontrollausdruck | - | Jeder Ausdruck (außer dem Kommaoperator), dessen Typ mit einem der Typnamen kompatibel sein muss, wenn die default-Assoziation nicht verwendet wird. |
| expression | - | Jeder Ausdruck (außer dem Kommaoperator) beliebigen Typs und beliebiger Wertkategorie. |
Keine zwei Typnamen in der Assoziationsliste dürfen kompatible Typen angeben. Es darf nur eine Assoziation geben, die das Schlüsselwort default verwendet. Wenn default nicht verwendet wird und keiner der Typnamen mit dem Typ des Kontrollausdrucks kompatibel ist, kompiliert das Programm nicht.
[bearbeiten] Erklärung
Zuerst unterliegt der Typ des Kontrollausdrucks Lvalue-Konvertierungen. Die Konvertierung erfolgt nur im Typdomäne: Sie verwirft die cvr-Qualifizierer auf oberster Ebene und die Atomizität und wendet Array-zu-Zeiger/Funktion-zu-Zeiger-Transformationen auf den Typ des Kontrollausdrucks an, ohne Nebenwirkungen auszulösen oder Werte zu berechnen.
Der Typ nach der Konvertierung wird mit den Typnamen aus der Liste der Assoziationen verglichen.
Wenn der Typ mit dem Typnamen einer der Assoziationen kompatibel ist, dann sind Typ, Wert und Wertkategorie der generischen Auswahl der Typ, der Wert und die Wertkategorie des Ausdrucks, der nach dem Doppelpunkt für diesen Typnamen steht.
Wenn keiner der Typnamen mit dem Typ des Kontrollausdrucks kompatibel ist und die default-Assoziation bereitgestellt wird, dann sind Typ, Wert und Wertkategorie der generischen Auswahl der Typ, der Wert und die Wertkategorie des Ausdrucks nach dem Label default :.
[bearbeiten] Hinweise
Der Kontrollausdruck und die Ausdrücke der nicht ausgewählten Optionen werden niemals ausgewertet.
Aufgrund der Lvalue-Konvertierungen entspricht "abc" char* und nicht char[4] und (int const){0} entspricht int und nicht const int.
Alle Wertkategorien, einschließlich Funktionsdeskriptoren und void-Ausdrücken, sind als Ausdrücke in einer generischen Auswahl zulässig, und wenn sie ausgewählt werden, hat die generische Auswahl selbst dieselbe Wertkategorie.
Die Typ-generischen mathematischen Makros aus <tgmath.h>, die in C99 eingeführt wurden, wurden compiler-spezifisch implementiert. Generische Auswahlen, die in C11 eingeführt wurden, gaben den Programmierern die Möglichkeit, ähnlichen typabhängigen Code zu schreiben.
Generische Auswahl ist ähnlich wie Überladung in C++ (wo eine von mehreren Funktionen zur Compile-Zeit basierend auf den Argumenttypen ausgewählt wird), außer dass sie die Auswahl zwischen beliebigen Ausdrücken ermöglicht.
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
#include <math.h> #include <stdio.h> // Possible implementation of the tgmath.h macro cbrt #define cbrt(X) _Generic((X), \ long double: cbrtl, \ default: cbrt, \ float: cbrtf \ )(X) int main(void) { double x = 8.0; const float y = 3.375; printf("cbrt(8.0) = %f\n", cbrt(x)); // selects the default cbrt printf("cbrtf(3.375) = %f\n", cbrt(y)); // converts const float to float, // then selects cbrtf }
Ausgabe
cbrt(8.0) = 2.000000 cbrtf(3.375) = 1.500000
[bearbeiten] Fehlerberichte
Die folgenden verhaltensändernden Defect Reports wurden rückwirkend auf zuvor veröffentlichte C-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| DR 481 | C11 | Es war unter-spezifiziert, ob der Kontrollausdruck Lvalue-Konvertierungen durchläuft. | Er durchläuft sie. |
[bearbeiten] Referenzen
- C23-Standard (ISO/IEC 9899:2024)
- 6.5.1.1 Generische Auswahl (S. TBD)
- C17-Standard (ISO/IEC 9899:2018)
- 6.5.1.1 Generische Auswahl (S. 56-57)
- C11-Standard (ISO/IEC 9899:2011)
- 6.5.1.1 Generische Auswahl (S. 78-79)
[bearbeiten] Siehe auch
| C++-Dokumentation für Templates
|