• [^] # Re: l'article est intéressants

    Posté par (site web personnel) . En réponse au lien Hans Peter Anvin : Kernel C++20 ? (article de qualité sur developpez.com). Évalué à 4.

    En C, t'a une erreur aussi (Vu que 1.0 est un double, il va dans le type default, donc cmpPtr)

     #include <stdio.h>
     #define cmp(a, b) _Generic(b, int : cmpInt, float: cmpFloat, default: cmpPtr)(a,b)
     int cmpPtr(void *a, void*b) {return a == b;}
     int cmpInt(int a, int b) {return a == b;}
     int cmpFloat(float a, float b) {return a == b;}
     int main()
     {
     printf("Hello, World! %d\n", cmp(1,1.0));
     }
    Main.c: In function ‘main’:
    Main.c:10:38: warning: passing argument 1 of ‘cmpPtr’ makes pointer from integer without a cast [-Wint-conversion]
     10 | printf("Hello, World! %d\n", cmp(1,1.0));
     | ^
     | |
     | int
    Main.c:3:79: note: in definition of macro ‘cmp’
     3 | #define cmp(a, b) _Generic(b, int : cmpInt, float: cmpFloat, default: cmpPtr)(a,b)
     | ^
    Main.c:5:18: note: expected ‘void *’ but argument is of type ‘int’
     5 | int cmpPtr(void *a, void*b) {return a == b;}
     | ~~~~~~^
    Main.c:10:40: error: incompatible type for argument 2 of ‘cmpPtr’
     10 | printf("Hello, World! %d\n", cmp(1,1.0));
     | ^~~
     | |
     | double
    Main.c:3:81: note: in definition of macro ‘cmp’
     3 | #define cmp(a, b) _Generic(b, int : cmpInt, float: cmpFloat, default: cmpPtr)(a,b)
     | ^
    Main.c:5:26: note: expected ‘void *’ but argument is of type ‘double’
     5 | int cmpPtr(void *a, void*b) {return a == b;}
     | ~~~~~^
    

    Si tu enlèves le default t'a aussi une erreur :

    Main.c: In function ‘main’:
    Main.c:10:40: error: ‘_Generic’ selector of type ‘double’ is not compatible with any association
     10 | printf("Hello, World! %d\n", cmp(1,1.0));
     | ^~~
    Main.c:3:28: note: in definition of macro ‘cmp’
     3 | #define cmp(a, b) _Generic(b, int : cmpInt, float: cmpFloat)(a,b)
     | 
    

    Ce que fait cmp, c'est juste appeler une fonction qui dépend du type de b (doc ici: https://www.iso-9899.info/n1570.html#6.5.1.1).
    Après si l'appelle de fonction déroulée pas la macro n'est pas bon, le compilateur va le remarquer.
    Dalleur utiliser default n'est généralement pas une super idée.

    si tu veux faire la même chose avec des macros en C++, ça va peu être plus compliqué.

    Cette remarque n'était pas pour dire que _Generic > template, mais que si tu essayes de reproduire le comportement des template C++ en macro C++, ça va effectivement être compliqué, et hasardeux.