2015-05-25 24 views
17

C'è un modo per convertire typeof estensione di gcc in una stringa, ad esempio:Conversione typeof a stringa

#define printType(a) printf("%s", #typeof(a)) 

In modo che io possa fare:

int a = 4; 
printf("Type of a is: "); 
printType(a); 

E ottenere l'output di:

Type of a is: int 

Un possibile utilizzo di questa sarebbe la seguente:

#include <stdio.h> 

#define indirect_print(a) print_##typeof(a)(a) 

void print_int(int *i) { 
    printf("%d", *i); 
} 

void print_char(char *c) { 
    printf("%c", *c); 
} 

int main(void) { 
    char C = 'C'; 
    int I = 100; 

    { 
     char *a = &C; 
     indirect_print(a); 
    } 

    { 
     int *a = &I; 
     indirect_print(a); 
    } 

    return 0; 
} 

Se possibile, dovrebbe funzionare per tutti i tipi, incluse strutture e unioni, senza dover aggiungere manualmente ogni tipo a un elenco.

+1

Si potrebbe provare a utilizzare una macro di tipo generico? –

+1

Perché vuoi farlo? –

risposta

17

Poiché C11, è possibile utilizzare un generico, vedere http://en.cppreference.com/w/c/language/generic. Ad esempio:

#define printType(a) printf("%s", _Generic((a) , \ 
            int : "int", \ 
            long : "long", \ 
            float : "float", \ 
            default : "other type"))(a) 

Ogni tipo che può essere utilizzato deve essere elencato.

In C++, v'è anche la parola chiave typeid:

#include <typeinfo> 
#define printType(a) std::cout << typeid(a).name() << std::endl; 
+0

Questo era esattamente quello che stavo cercando! – user2868331

+0

'_Generic' ha alcune ambiguità sui selettori di tipo. Vedere i collegamenti nella mia risposta prima di fare affidamento soprattutto sui tipi qualificati. – Olaf

5

Il processore pre viene eseguito prima del compilatore. Quindi tutte le sue sostituzioni vengono eseguite prima dell'avvio della compilazione effettiva. typeof() viene valutato dal compilatore, che vedrà solo una stringa "typeof()" che ovviamente non verrà valutata.

Quindi, la risposta è: non per pre-C11. Per C11, vedere la risposta di @tmlen, ma tenere presente che vi sono alcune ambiguità sui selettori di tipo _Generic che sono stati risolti in modo diverso in diversi compilatori, il che può causare problemi con tipi qualificati. C'è un rapporto sui difetti su questo problema, leggi il blob di Jens Gustedt per i dettagli: https://gustedt.wordpress.com/2015/05/11/the-controlling-expression-of-_generic/#more-2256 (ha anche depositato un rapporto sui difetti http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_423.htm).