我正在编写一个struct
的程序,需要存储有关它所持有的类型的信息。数据在结构内部表示为指向void的指针。我的意思的一个简短例子:
#include <stdio.h>
struct foo {
void *data;
char *type;
};
int main() {
struct foo bar = {{'a', 'b', 'c'}, "char"};
printf("%s\n", (STRING_TO_TYPE(bar.type))bar.data);
return 0;
}
我需要STRING_TO_TYPE
宏的实现,它将"char"
替换为char
。所有这些都可以在编译时根据我的程序的需要进行评估
我想要做的是保持任何类型的对象,因此使用enum
或检查字符串相等将不起作用。
答案 0 :(得分:1)
简短回答:这是不可能的。不是你的方式。宏可以生成标记(关键字,如果您愿意),但不能将字符串转换为它们。
那就是说,如果你追求的东西真的是
struct
void *
的“{1}} struct
的名称那么你很可能会以typeof
结束。它是一个GNU extension,所以它只适用于GCC,但它可以工作。
在此处的示例代码中,您使用MYSTRUCT宏定义某个“类型”的struct
,并使用TYPE宏获取类型。 __COUNTER __ predefined macro会阻止类型重新定义(每个struct
都是它自己的类型,请参阅gcc -E
),MYSTRUCT的三个宏级别用于正确的字符串化。
#include <stdio.h>
#define TYPE(x) typeof(x.type)
#define MYSTRUCT(name, type) MYSTRUCT_INTER(name, type, __COUNTER__)
#define MYSTRUCT_INTER(name, type, counter) MYSTRUCT_RAW(name, type, counter)
#define MYSTRUCT_RAW(xName, xType, xCounter) \
struct mystruct_## xCounter { \
void * data; \
xType type; \
} xName
int main(void) {
MYSTRUCT(foo, int);
foo.data = (void *)42;
TYPE(foo) tmp = foo.data; /* <-- Here, tmp is an int */
printf("%d\n", tmp);
MYSTRUCT(bar, int*);
bar.data = &tmp;
TYPE(bar) tmp2 = bar.data; /* <-- Here, tmp2 is an int* */
printf("%p\n", tmp2);
MYSTRUCT(baz, char*);
baz.data = "Hello world";
printf("%s\n", (TYPE(baz))baz.data);
/* ^Expands to (char *) baz.data */
}
请注意,我仍然需要知道struct
的“类型”以确定printf()
的格式代码,但未解决此问题。
不要忘记使用-std=gnu**
进行编译(typeof