我想要一个打印出结构成员变量信息的函数。为了使函数尽可能简单(并且没有错误),我也不想手动传入类型。这使我需要能够评估传递给我的宏的参数:
#ifndef preprocessor_stringify
#define preprocessor_stringify(s) #s
#endif
typedef struct test_s {
void (*ptr)(void*);
} test;
void doSomething_(char *name, int offset, int size){
printf("%s %d %d\n", name, offset, size);
}
#define doSomething(name, container) (\
doSomething_(\
preprocessor_stringify(name),\
offsetof(container, name),\
sizeof(container->name))\
);
int main(){
doSomething(ptr, test);
return 0;
}
这会产生编译错误
test.cpp:21:19: error: expected primary-expression before ‘->’ token
sizeof(container->name))\
有关如何解决此问题的任何想法?我希望解决方案兼容c和c ++。
答案 0 :(得分:6)
#include <stdio.h>
#include <stddef.h>
#ifndef preprocessor_stringify
#define preprocessor_stringify(s) #s
#endif
typedef struct test_s {
void (*ptr)(void*);
} test;
void doSomething_(char const *name, int offset, int size){
printf("%s %d %d\n", name, offset, size);
}
#define doSomething(name, container) (\
doSomething_(\
preprocessor_stringify(name),\
offsetof(container, name),\
sizeof(((container*)0)->name))\
);
int main(){
doSomething(ptr, test);
return 0;
}
我做了两处修改:
const char[]
void doSomething_(char const *name, int offset, int size){
sizeof(((container*)0)->name))\
其中一条评论提到指针转换是丑陋的。我同意,让我们把它限制在一个我们可以重复使用的宏。
#define sizeof_member(Class, Member) sizeof ((Class*)0)->Member
#define doSomething(name, container) (\
doSomething_(\
preprocessor_stringify(name),\
offsetof(container, name),\
sizeof_member(container, name)) \
);
答案 1 :(得分:-1)
另一种选择是使用临时对象。
#define doSomething(name, container) \
do { \
container temp; \
doSomething_( \
preprocessor_stringify(name), \
offsetof(container, name), \
sizeof(temp.name) \
); \
} while(0)
很可能该对象被优化掉了。 (可能不适用于复杂的C ++对象)。