Namespaces
Variants

Generic selection (since C11)

From cppreference.net

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

_Generic , default

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