我正在尝试编写一个宏来协助C语言中的面向对象编程。当我将类信息存储在一个常量结构中时,我需要创建一个执行以下操作的宏:
_info
以获取所需classInfo结构的名称destroyObject
函数一个例子:
queue_t* p = NULL;
delete(p);
delete
应扩展为:
destroyObject(&(queue_t_info), p);
我尝试使用这个宏,但我无法开始工作:
#define delete(X) (destroyObject(&(typeof(*X)##_info), X))
我遇到类型部件无法正常工作的问题。
答案 0 :(得分:6)
typeof
不是宏,它是语言构造,它是由编译器扩展的,而不是预处理器。由于预处理在编译之前进行,因此宏无法访问typeof
结果。
您的delete(p)
已扩展为:(destroyObject(&(typeof(*p)_info), p))
。 (你可以通过-E
gcc标志看到它)
答案 1 :(得分:2)
我意识到我试图做的事情是不可能的 - C预处理器不解析和符号化代码,因此它不知道变量是哪种类型。
要解决这个问题,我还要求将类型传递给删除函数。这并不理想,因为它引入了由于类型不匹配而导致的错误频繁来源。如果程序员将指针传递给对象A但在delete函数中指定了对象B,则会调用错误的析构函数。为了解决这个问题,我在宏中添加了一个类型检查,以便为任何不匹配的类型生成编译器警告。
#define typecheck(type,x) \
({ type __dummy; \
typeof(x) __dummy2; \
(void)(&__dummy == &__dummy2); \
})
#define delete(P, X) (destroyObject(&(X##_info), P), typecheck(X, *P))
#define new(X, ...) (createObject(&(X##_info), ##__VA_ARGS__))
宏的正常用法:
queue_t* p = new(queue_t);
delete(p, queue_t);
但是使用了错误的类型:
queue_t* p = new(queue_t);
delete(p, int);
导致编译器警告:
Comparison of distinct pointer types ('int *' and 'typeof (*p) *' (aka 'queue_t *'))