Eu tenho uma função chamada create_car
. Estou tentando usar uma macro de pré-processador para poder chamar a função fazendo Create(car)
. Aqui está o que tenho até agora:
#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);
}
Mas, ao tentar fazer isso, recebo o seguinte erro:
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)
O que parece o problema acima com a forma como estou tentando criar o objeto da macro?
O que pretendo que o código se torne depois de pré-processado / compilado é:
int main(void)
{
struct Car *car = create_car();
}
Você não pode fazer dessa maneira. O pré-processador C não conhece _Generic
. Tratará é um nome normal, um candidato potencial para expansão futura.
No entanto, você pode usar _Generic
na definição da macro NewObj. A questão é que o argumento de NewObj(X)
não é um valor, mas um tipo. No entanto, você pode contorná-lo enviando um ponteiro NULL X
para localizar uma função construtora adequada.
#define NewObj(X) _Generic(((X*)0), struct Person*: create_person(), struct Car*: create_car())
O código resultante simplificado seria:
#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;
}
Imprime conforme o esperado:
Create a car
Create a person
De qualquer forma, sugiro ligando create_car()
/ create_person()
directamente, uma vez que é mais legível.
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras