Zoeken…


Syntaxis

  • _Generic (opdracht-expressie, generieke-assoc-lijst)

parameters

Parameter Details
generic-assoc-lijst generieke-associatie OF generieke-assoc-lijst, generieke-associatie
generic-vereniging type-naam: opdracht-uitdrukking OF standaard: opdracht-uitdrukking

Opmerkingen

  1. Alle _Generic worden verwijderd tijdens de evaluatie van _Generic primaire expressie.
  2. _Generic primaire expressie wordt geëvalueerd in vertaalfase 7 . Dus fasen zoals string-aaneenschakeling zijn voltooid vóór de evaluatie.

Controleer of een variabele van een bepaald gekwalificeerd type is

#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));
}

Output:

i is a const int
j is a non-const int
k is of other type

Als het type generieke macro echter als volgt wordt geïmplementeerd:

#define is_const_int(x) _Generic((x), \
        const int: "a const int",     \
        int:       "a non-const int", \
        default:   "of other type")

De output is:

i is a non-const int
j is a non-const int
k is of other type

Dit komt omdat alle _Generic zijn verwijderd voor de evaluatie van de controlerende expressie van een _Generic primaire expressie.

Type-generieke afdrukmacro

#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");
}

Output:

int: 42
double: 3.14
unknown argument

Merk op dat als het type noch int noch double , een waarschuwing zou worden gegenereerd. Om de waarschuwing te elimineren, kunt u dat type toevoegen aan de macro voor print(X) .

Algemene selectie op basis van meerdere argumenten

Als een selectie op meerdere argumenten voor een generieke expressie van het type gewenst is, en alle typen in kwestie rekenkundige typen zijn, is een eenvoudige manier om geneste _Generic expressies te voorkomen het toevoegen van de parameters in de controlerende expressie:

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))

Hier wordt de controlerende expressie (X)+(Y) alleen geïnspecteerd op basis van het type en niet geëvalueerd. De gebruikelijke conversies voor rekenkundige operanden worden uitgevoerd om het geselecteerde type te bepalen.

Voor een meer complexe situatie kan een selectie worden gemaakt op basis van meer dan één argument aan de operator, door ze samen te nestelen.

Dit voorbeeld selecteert tussen vier extern geïmplementeerde functies, die combinaties van twee int en / of stringargumenten nemen en hun som teruggeven.

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 );
}

Hoewel het lijkt alsof argument y meer dan eens wordt geëvalueerd, is het niet 1 . Beide argumenten worden slechts eenmaal geëvalueerd, aan het einde van macro Toevoegen: ( x , y ) , net als bij een gewone functieaanroep.


1 (Geciteerd uit: ISO: IEC 9899: 201X 6.5.1.1 Algemene selectie 3)
De controlerende expressie van een generieke selectie wordt niet geëvalueerd.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow