Преобразование typeof в строку
есть ли способ конвертировать gcc в typeof
расширение строки, например:
#define printType(a) printf("%s", #typeof(a))
так что я могу сделать:
int a = 4;
printf("Type of a is: ");
printType(a);
и получить результат:
Type of a is: int
возможное использование этого будет следующим:
#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;
}
если это возможно, он должен работать для всех типов, включая структуры и объединения, не полагаясь на добавление каждого типа в список вручную.
2 ответов
начиная с C11, вы можете использовать общий, см. http://en.cppreference.com/w/c/language/generic. Например:
#define printType(a) printf("%s", _Generic( (a) , \
int : "int", \
long : "long", \
float : "float", \
default : "other type"))(a)
каждый тип, который может быть использован для.
В C++ также есть typeid
ключевые слова:
#include <typeinfo>
#define printType(a) std::cout << typeid(a).name() << std::endl;
на preпроцессор запускается перед компилятором. Таким образом, все его замены выполняются до начала фактической компиляции. typeof()
обрабатывается компилятором, который будет видеть только строку "typeof()"
который, очевидно, не будет оценен.
Итак, ответ: не для pre-C11. Для C11 см. ответ @tmlen, но имейте в виду, что есть некоторые двусмысленности относительно _Generic
селекторы типов, которые разрешаются по-разному в разных компиляторах, что может привести в проблемах с квалифицированными типами. Существует отчет о дефекте об этой проблеме, прочитайте blob Йенса Гюштедта для деталей: https://gustedt.wordpress.com/2015/05/11/the-controlling-expression-of-_generic/#more-2256 (он также подал отчет о дефекте http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_423.htm).