Generic selection (since C11)
Bietet eine Möglichkeit, zur Kompilierzeit einen von mehreren Ausdrücken basierend auf dem Typ eines kontrollierenden Ausdrucks auszuwählen
Inhaltsverzeichnis |
Syntax
_Generic
(
Steuerausdruck
,
Assoziationsliste
)
|
(seit C11) | ||||||||
wobei association-list eine durch Kommas getrennte Liste von Assoziationen ist, von denen jede die folgende Syntax hat
Typname
:
Ausdruck
|
|||||||||
default
:
Ausdruck
|
|||||||||
wo
| type-name | - | jeder vollständige Objekttyp , der nicht variabel-modifiziert ist (d.h. kein VLA oder Zeiger auf VLA). |
| controlling-expression | - | jeder Ausdruck (außer dem Komma-Operator ), dessen Typ mit einem der type-name s kompatibel sein muss, wenn die default -Assoziation nicht verwendet wird |
| expression | - | jeder Ausdruck (außer dem Komma-Operator ) beliebigen Typs und Wertkategorie |
Keine zwei type-name s in der association-list 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 type-name s mit dem Typ des kontrollierenden Ausdrucks kompatibel ist, wird das Programm nicht kompiliert.
Erklärung
Zunächst unterliegt der Typ des controlling-expression den Lvalue-Konvertierungen . Die Konvertierung erfolgt ausschließlich im Typbereich: Sie verwirft die obersten cvr-Qualifizierer und die Atomarität und wendet Array-zu-Zeiger-/Funktion-zu-Zeiger-Transformationen auf den Typ des kontrollierenden Ausdrucks an, ohne Nebeneffekte zu initiieren oder Werte zu berechnen.
Der Typ nach der Konvertierung wird mit type-name s aus der Liste der Assoziationen verglichen.
Wenn der Typ kompatibel mit dem type-name einer der Assoziationen ist, dann sind der Typ, der Wert und die value category der generischen Selektion der Typ, der Wert und die Wertkategorie des expression , der nach dem Doppelpunkt für diesen type-name erscheint.
Wenn keiner der
type-name
s mit dem Typ des
controlling-expression
kompatibel ist, und die
default
-Assoziation bereitgestellt wird, dann sind der Typ, Wert und Wertkategorie der generischen Auswahl der Typ, Wert und Wertkategorie des Ausdrucks nach dem
default :
-Label.
Hinweise
Der controlling-expression und die expression s der nicht gewählten Selektionszweige werden niemals ausgewertet.
Aufgrund der Lvalue-Konvertierungen passt "abc" zu char * und nicht zu char [ 4 ] , und ( int const ) { 0 } passt zu int , und nicht zu const int .
Alle value categories , einschließlich Funktionsbezeichnern und void-Ausdrücken, sind als expression s in einer generischen Auswahl zulässig, und falls ausgewählt, hat die generische Auswahl selbst dieselbe value category.
Die typengenerischen Mathematik-Makros aus <tgmath.h> , eingeführt in C99, wurden auf compilerspezifische Weise implementiert. Generische Selektionen, eingeführt in C11, gaben Programmierern die Möglichkeit, ähnlichen typabhängigen Code zu schreiben.
Generische Auswahl ähnelt dem Überladen in C++ (bei dem eine von mehreren Funktionen zur Kompilierzeit basiernd auf den Typen der Argumente ausgewählt wird), mit dem Unterschied, dass sie die Auswahl zwischen beliebigen Ausdrücken trifft.
Schlüsselwörter
Beispiel
#include <math.h> #include <stdio.h> // Mögliche Implementierung des tgmath.h-Makros 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)); // wählt das default-cbrt aus printf("cbrtf(3.375) = %f\n", cbrt(y)); // konvertiert const float zu float, // wählt dann cbrtf aus }
Ausgabe:
cbrt(8.0) = 2.000000 cbrtf(3.375) = 1.500000
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| DR 481 | C11 | Es war nicht ausreichend spezifiziert, ob der steuernde Ausdruck Lvalue-Konvertierungen durchläuft | Er durchläuft sie |
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)
Siehe auch
|
C++ Dokumentation
für
Templates
|