如何计算预处理器宏中的参数以传递给 sizeof?



我想要一个函数来打印出有关结构的成员变量的信息。为了使函数尽可能简单(且无错误(,我也不想手动传入类型。这导致我需要能够评估传递到我的宏中的参数:

#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;
}

我做了两个更改:

  1. 在 c++ 中,字符串文本是const char[]

 

void doSomething_(char const *name, int offset, int size){
  1. 我们想要一个模型对象的大小,所以我们必须创建一个模型:

 

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++对象(。

最新更新