我想要一个函数来打印出有关结构的成员变量的信息。为了使函数尽可能简单(且无错误(,我也不想手动传入类型。这导致我需要能够评估传递到我的宏中的参数:
#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 %dn", 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++ 兼容。
#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 %dn", 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;
}
我做了两个更改:
- 在 c++ 中,字符串文本是
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))
);
另一种选择是使用临时对象。
#define doSomething(name, container)
do {
container temp;
doSomething_(
preprocessor_stringify(name),
offsetof(container, name),
sizeof(temp.name)
);
} while(0)
该对象很可能被优化掉了。(可能不适用于复杂C++对象(。