C Language                
            Wybór ogólny
        
        
            
    Szukaj…
Składnia
- _Generic (wyrażenie przypisania, ogólna lista assoc)
Parametry
| Parametr | Detale | 
|---|---|
| ogólna lista assoc | ogólna asocjacja OR ogólna lista assoc, ogólna asocjacja | 
| ogólne skojarzenie | typ-nazwa: przypisanie-wyrażenie LUB domyślnie: przypisanie-wyrażenie | 
Uwagi
-  Wszystkie kwalifikatory typu zostaną usunięte podczas oceny _Genericpierwotnego wyrażenia.
-  _Genericekspresja pierwotna jest oceniana w fazie translacji 7 . Tak więc fazy takie jak konkatenacja łańcuchów zostały zakończone przed ich oceną.
Sprawdź, czy zmienna jest określonego typu kwalifikowanego
#include <stdio.h> 
#define is_const_int(x) _Generic((&x),  \
        const int *: "a const int",     \
        int *:       "a non-const int", \
        default:     "of other type")
int main(void)
{
    const int i = 1;
    int j = 1;
    double k = 1.0;
    printf("i is %s\n", is_const_int(i));
    printf("j is %s\n", is_const_int(j));
    printf("k is %s\n", is_const_int(k));
}
Wynik:
i is a const int
j is a non-const int
k is of other type
Jeśli jednak ogólne makro typu jest zaimplementowane w następujący sposób:
#define is_const_int(x) _Generic((x), \
        const int: "a const int",     \
        int:       "a non-const int", \
        default:   "of other type")
Dane wyjściowe to:
i is a non-const int
j is a non-const int
k is of other type
 Wynika to z tego, że wszystkie kwalifikatory typu są odrzucane w celu oceny kontrolnego wyrażenia _Generic pierwotnego wyrażenia. 
Makro drukowania typu ogólnego
#include <stdio.h>
void print_int(int x) { printf("int: %d\n", x); }
void print_dbl(double x) { printf("double: %g\n", x); }
void print_default() { puts("unknown argument"); }
#define print(X) _Generic((X), \
        int: print_int, \
        double: print_dbl, \
        default: print_default)(X)
int main(void) {
    print(42);
    print(3.14);
    print("hello, world");
}
Wynik:
int: 42
double: 3.14
unknown argument
 Zauważ, że jeśli typ nie jest ani int ani double , zostanie wygenerowane ostrzeżenie. Aby wyeliminować ostrzeżenie, możesz dodać ten typ do makra print(X) . 
Wybór ogólny na podstawie wielu argumentów
 Jeśli pożądany jest wybór wielu argumentów dla wyrażenia ogólnego typu, a wszystkie omawiane typy są typami arytmetycznymi, łatwym sposobem na uniknięcie zagnieżdżonych wyrażeń _Generic jest użycie dodania parametrów w wyrażeniu kontrolnym: 
int max_int(int, int);
unsigned max_unsigned(unsigned, unsigned);
double max_double(double, double);
#define MAX(X, Y) _Generic((X)+(Y),                \
                           int:      max_int,      \
                           unsigned: max_unsigned, \
                           default:  max_double)   \
                    ((X), (Y))
 W tym przypadku wyrażenie kontrolne (X)+(Y) jest sprawdzane tylko zgodnie z jego typem i nie jest oceniane. Zwykłe konwersje dla argumentów arytmetycznych są wykonywane w celu określenia wybranego typu. 
W przypadku bardziej złożonej sytuacji można dokonać wyboru na podstawie więcej niż jednego argumentu dla operatora, zagnieżdżając je razem.
W tym przykładzie wybrano cztery zewnętrznie zaimplementowane funkcje, które pobierają kombinacje dwóch argumentów int i / lub string i zwracają ich sumę.
int AddIntInt(int a, int b);
int AddIntStr(int a, const char* b);
int AddStrInt(const char*  a, int b );
int AddStrStr(const char*  a, const char*  b);
#define AddStr(y)                            \
   _Generic((y),         int: AddStrInt,     \
                        char*: AddStrStr,    \
                  const char*: AddStrStr )
#define AddInt(y)                            \
   _Generic((y),          int: AddIntInt,    \
                        char*: AddIntStr,    \
                  const char*: AddIntStr )
#define Add(x, y)                            \
   _Generic((x) ,        int: AddInt(y) ,    \
                       char*: AddStr(y) ,    \
                 const char*: AddStr(y))     \
                         ((x), (y))
int main( void )
{
    int result = 0;
    result = Add( 100 , 999 );
    result = Add( 100 , "999" );
    result = Add( "100" , 999 );
    result = Add( "100" , "999" );
    const int a = -123;
    char b[] = "4321";
    result = Add( a , b );
    int c = 1;
    const char d[] = "0";
    result = Add( d , ++c );
}
 Chociaż wydaje się, że argument y jest oceniany więcej niż jeden raz, nie jest to 1 . Oba argumenty są oceniane tylko raz, na końcu makra Add: ( x , y ) , tak jak w zwykłym wywołaniu funkcji. 
 1 (Cytat z: ISO: IEC 9899: 201X 6.5.1.1 Wybór ogólny 3) 
 Kontrolne wyrażenie wyboru ogólnego nie jest oceniane.