2015-05-25 14 views
17

Czy istnieje sposób przekonwertować GCC typeof rozszerzenie na sznurku, na przykład:Konwersja typeof ciąg

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

Więc co mogę zrobić:

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

i uzyskać wyjście:

Type of a is: int 

możliwe zastosowanie to będzie w następujący sposób:

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

Jeśli to możliwe, powinien działać dla wszystkich typów, w tym struktur i związków, bez polegania na ręcznym dodawaniu każdego typu do listy.

+1

Można spróbować użyć typu-generic makro? –

+1

Dlaczego chcesz to zrobić? –

Odpowiedz

17

Od wersji C11 można użyć nazwy ogólnej, patrz http://en.cppreference.com/w/c/language/generic. Na przykład:

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

Każdy typ, którego można użyć, musi być wymieniony.

W C++ istnieje również typeid kluczowe:

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

To było dokładnie to, czego szukałem! – user2868331

+0

'_Generic' ma pewne niejasności dotyczące selektorów typu. Zobacz linki w mojej odpowiedzi przed opieraniem się na kwalifikowanych typach, szczególnie. – Olaf

5

Procesor pre działa przed kompilatorem. Wszystkie jego zamienniki są wykonywane przed rozpoczęciem kompilacji. typeof() jest oceniany przez kompilator, który będzie widział tylko ciąg znaków "typeof()", który oczywiście nie zostanie oceniony.

Odpowiedź brzmi: nie dla pre-C11. Jeśli chodzi o C11, zobacz odpowiedź @tmlen, ale należy pamiętać, że istnieją pewne niejasności dotyczące selektorów typu _Generic, które są rozwiązywane różnie w różnych kompilatorach, co może powodować problemy z kwalifikowanymi typami. Istnieje raport o usterce dotyczący tego problemu, przeczytaj blob Jensa Gustedta o szczegółach: https://gustedt.wordpress.com/2015/05/11/the-controlling-expression-of-_generic/#more-2256 (on również złożył raport o usterkach http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_423.htm).