【问题标题】:Converting typeof to string将 typeof 转换为字符串
【发布时间】:2015-08-06 22:36:45
【问题描述】:

有没有办法将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;
}

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

【问题讨论】:

  • 您可以尝试使用泛型宏吗?
  • 你为什么要这样做?

标签: c gcc typeof


【解决方案1】:

从 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;

【讨论】:

  • 这正是我想要的!
  • _Generic 对类型选择器有一些歧义。在特别依赖合格类型之前,请参阅我的答案中的链接。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 2019-10-10
    • 2019-01-05
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多