我有一个名为create_car
的函数。我正在尝试使用预处理器宏,以便可以通过执行 Create(car)
来调用该函数。这是我迄今为止所拥有的:
#define ObjName(X) _Generic((X), struct Person: "person", struct Car: "car")
#define NewObj(X) create_ ## ObjName(X)
struct Car* create_car(void)
{
// do something here
}
struct Car {
char* make;
char* model;
int year;
void (*print)(struct Car*);
};
int main(void)
{
struct Car *car = NewObj(struct Car);
}
但是在尝试时出现以下错误:
gen.c:5:21: warning: implicit declaration of function ‘create_ObjName’; did you mean ‘create_car’? [-Wimplicit-function-declaration]
#define NewObj(X) create_ ## ObjName(X)
^
gen.c:40:5: note: in expansion of macro ‘NewObj’
NewObj(struct Car);
^~~~~~
gen.c:40:12: error: expected expression before ‘struct’
NewObj(struct Car);
^
gen.c:5:40: note: in definition of macro ‘NewObj’
#define NewObj(X) create_ ## ObjName(X)
我如何尝试从宏创建对象时,上面出现的问题是什么?
我正在寻找预处理/编译后的代码:
int main(void)
{
struct Car *car = create_car();
}
最佳答案
你不能这样做。 C 预处理器不知道 _Generic
。它将视为一个普通名称,一个进一步扩展的潜在候选名称。
但是,您可以在 NewObj 宏的定义中使用_Generic
。
问题是 NewObj(X) 的参数不是值而是类型。
但是,您可以通过将 NULL 指针分派(dispatch)到 X
来绕过它
找到合适的构造函数。
#define NewObj(X) _Generic(((X*)0), struct Person*: create_person(), struct Car*: create_car())
简化的结果代码是:
#include <stdio.h>
struct Car;
struct Person;
struct Car* create_car(void) {
puts("Create a car");
return NULL;
}
struct Person* create_person(void) {
puts("Create a person");
return NULL;
}
#define NewObj(X) _Generic(((X*)0), struct Person*: create_person(), struct Car*: create_car())
int main(void)
{
struct Car *car = NewObj(struct Car);
struct Person *person = NewObj(struct Person);
return 0;
}
按预期打印:
Create a car
Create a person
无论如何,我建议直接调用create_car()
/create_person()
,因为它更具可读性。
关于c - 使用预处理器##动态调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66450490/