将typeof转换为字符串

use*_*331 17 c gcc typeof

有没有办法将gcc的typeof扩展名转换为字符串,例如:

#define printType(a) printf("%s", #typeof(a))
Run Code Online (Sandbox Code Playgroud)

所以我可以这样做:

int a = 4;
printf("Type of a is: ");
printType(a);
Run Code Online (Sandbox Code Playgroud)

得到的输出:

Type of a is: int
Run Code Online (Sandbox Code Playgroud)

可能的用法如下:

#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;
}
Run Code Online (Sandbox Code Playgroud)

如果可能,它应该适用于所有类型,包括结构和联合,而不依赖于手动将每个类型添加到列表.

tml*_*len 17

从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)
Run Code Online (Sandbox Code Playgroud)

可以使用每种可以使用的类型.

在C++中,还有typeid关键字:

#include <typeinfo>
#define printType(a) std::cout << typeid(a).name() << std::endl;
Run Code Online (Sandbox Code Playgroud)


too*_*ite 5

处理器编译器之前运行.所以它的所有替换都是在实际编译开始之前执行的.typeof()由编译器评估,编译器只会看到一个"typeof()"显然不会被评估的字符串.

所以,答案是:不适用于C11之前.对于C11,请参阅@tmlen的答案,但请注意,对于_Generic在不同编译器中以不同方式解析的类型选择器存在一些含糊之处,这可能导致合格类型出现问题.有一个关于这个问题的一个缺陷报告,读延Gustedt对细节的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).