c - 如何在C代码中获取变量的类型?

标签 c gcc types openmp typeof

有什么方法可以让我在 C 语言中自动发现变量的类型,要么通过程序本身的某种机制,要么——更可能的是——通过一个预编译脚本,该脚本使用编译器传递到它在哪里解析了变量并为它们分配了类型?我正在寻找有关此的一般建议。下面是关于我需要什么以及为什么需要的更多背景信息。

我想更改 OpenMP 缩减条款的语义。在这一点上,似乎最简单的方法是将源代码中的子句(通过脚本)替换为对函数的调用,然后我可以定义函数来实现我想要的归约语义。例如,我的脚本会转换这个

#pragma omp parallel for reduction(+:x)

进入这个:

my_reduction(PLUS, &x, sizeof(x));
#pragma omp parallel for

哪里,早些时候,我有(说)

enum reduction_op {PLUS, MINUS, TIMES, AND,
  OR, BIT_AND, BIT_OR, BIT_XOR, /* ... */};

my_reduction 有签名

void my_reduction(enum reduction_op op, void * var, size_t size);

除其他事项外,my_reduction 必须按照程序员最初的意图将加法运算应用于归约变量。但是我的功能不知道如何正确地做到这一点。特别是,虽然它知道操作的种类(PLUS)、原始变量的位置(var)和变量类型的大小,但它不知道变量的类型本身。特别是,它不知道 var 是整型还是浮点型。从低级 POV 来看,这两种类型的加法操作是完全不同的。

如果 GCC 支持的非标准运算符 typeof 能够像 sizeof 那样工作——返回某种类型的变量——我就能轻松解决这个问题。但是 typeof 并不像 sizeof:它显然只能用于左值声明。

现在,编译器在完成生成可执行代码之前显然知道 x 的类型。这让我想知道我是否可以以某种方式利用 GCC 的解析器,只是为了获取 x 的类型并将其传递给我的脚本,然后再次运行 GCC,一路编译我修改过的源代码.然后声明就很简单了

enum var_type { INT8, UINT8, INT16, UINT16, /* ,..., */ FLOAT, DOUBLE};
void my_reduction(enum reduction_op op, void * var, enum var_type vtype);

my_reduction 可以在取消引用和应用运算符之前进行适当的转换。

如您所见,我试图在 C 中创建一种"dispatch"机制。为什么不直接使用 C++ 重载呢?因为我的项目限制我使用用 C 编写的遗留源代码。我可以使用脚本自动更改代码,但我不能将其重写为其他语言。

谢谢!

最佳答案

C11 _Generic

不是直接的解决方案,但如果您有耐心对所有类型进行编码,它确实可以让您获得预期的结果:

#include <assert.h>
#include <string.h>

#define typename(x) _Generic((x), \
    int:     "int", \
    float:   "float", \
    default: "other")

int main(void) {
    int i;
    float f;
    void* v;
    assert(strcmp(typename(i), "int")   == 0);
    assert(strcmp(typename(f), "float") == 0);
    assert(strcmp(typename(v), "other") == 0);
}

编译并运行:

gcc -std=c11 a.c
./a.out

可以找到大量类型的良好起点 in this answer .

在 Ubuntu 17.10、GCC 7.2.0 中测试。 GCC 仅在 4.9 中添加了支持。

关于c - 如何在C代码中获取变量的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9156226/

相关文章:

types - 当他们谈论 "uniqued types"和 "types in LLVM are uniqued"时,他们在谈论什么?

c - 数组、分配、困惑

c - Bison和Flex到达EOF时不会停止,只说 "Reading a token:"并等待输入

在 union 中组合指针和整数

c - 需要左值作为赋值的左操作数 - 编译错误不清楚

c - 这是什么意思,我该如何纠正它 *** 检测到堆栈粉碎 *** : ./array1output 终止

c++ - 设计一个只有 1 个可能实例的类/类型 - C++

mysql - 我应该使用 0/1 还是 True/False boolean 值?

c - 如何使用给定的汇编代码查找 C 代码中变量之间的间隙值?

c - 警告 : incompatible implicit declaration of built-in function 'function xyz' [enabled by default]