C macro get typeof argument

▼魔方 西西 提交于 2021-02-08 17:01:01

问题


I am trying to write a macro to assist with object oriented programming in C. As I store the class information in a constant struct, I need to create a macro that does the following:

  • Take the type of the object (typeof the derefenced pointer)
  • Append _info to get the name of the desired classInfo struct
  • Take the address of that symbol so it can be passed to the function
  • Call the destroyObject function with a pointer to the class struct and the object itself

An example:

queue_t* p = NULL;
delete(p);

delete should expand to:

destroyObject(&(queue_t_info), p);

I tried using this macro, but I can't get to to work:

#define delete(X) (destroyObject(&(typeof(*X)##_info), X))

I'm having trouble with the typeof part to work correctly.


回答1:


typeof isn't macro, it is language construction and it is expanded by compiler, not preprocessor. Since preprocessing goes before compilation, macro can't access typeof result.

Your delete(p) is expanded to: (destroyObject(&(typeof(*p)_info), p)). (You can see it by -E gcc flag)




回答2:


I realized that what I was attempting to do was impossible - the C preprocessor doesn't parse and symbolize the code so it doesn't know which type a variable is.

To solve this, I require the type to be passed into the delete function as well. This isn't ideal as it introduces a frequent source of bugs due to mismatched types. If a programmer passes a pointer to object A but specifies object B in the delete function, the wrong destructor would be called. To solve this, I added a typecheck to the macro so that a compiler warning would be generated for any mismatched types.

#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__))

Normal usage of the macro:

queue_t* p = new(queue_t);
delete(p, queue_t);

However using the wrong type:

queue_t* p = new(queue_t);
delete(p, int);

causes a compiler warning:

Comparison of distinct pointer types ('int *' and 'typeof (*p) *' (aka 'queue_t *'))


来源:https://stackoverflow.com/questions/15086794/c-macro-get-typeof-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!