voglio usare la parola chiave C11_Generic
per riempire un sindacato in base al tipo statico, come:_Generic per riempire un po 'di unione
typedef union {
double d;
long l;
const char*s;
void*p;
} ty;
#define make_ty(X) _Generic((X), \
double: (ty){.d=(X)}, \
long: (ty){.l=(X)}, \
const char*: (ty){.s=(X)}, \
default: (ty){.p=(X)})
ty from_double(double x) { return make_ty(x); }
ty from_string(const char*s) { return make_ty(s); }
ty from_long(long l) { return make_ty(l);}
ma questo non viene compilato, ad esempio, GCC 5.3 dà (con gcc -std=c11 -Wall
):
u.c: In function ‘from_double’:
u.c:11:35: error: incompatible types when initializing type ‘const char *’
using type ‘double’
const char*: (ty){.s=(X)}, \
^
u.c:14:41: note: in expansion of macro ‘make_ty’
ty from_double(double x) { return make_ty(x); }
BTW, utilizzando gcc -std=c99 -Wall
dà lo stesso errore ...
o è _Generic
utile solo per tgmath.h
?
ho pensato che _Generic
sceglie l'espressione a seconda del tipo compilatore noto, in modo che il non-sensical (ty){.s=(x)}
sarebbero ignorati in from_double
....
(se questo ha funzionato, sarei in grado di "sovraccarico" make_ty
secondo la statica, compilatore noto, tipo dell'argomento ...)
Ok, ma anche in '-std = c11' questo non funziona –
[Questa domanda] (http://stackoverflow.com/questions/24743520/incompatible-pointer-types-passing-in-generic-macro) ha un problema simile e la risposta più alta probabilmente risponde alla tua domanda –
Altre risposte sullo stesso argomento sembrano suggerire che gli altri casi non siano autorizzati a contenere una violazione * del vincolo * (il tipo errato per l'inizializzatore è effettivamente uno di quelli) –