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)intcmpPtr(void*a,void*b){returna==b;}intcmpInt(inta,intb){returna==b;}intcmpFloat(floata,floatb){returna==b;}intmain(){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.
[^] # Re: l'article est intéressants
Posté par uso (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)
Si tu enlèves le default t'a aussi une erreur :
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.
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.