Usando o pré-processador ## para chamar uma função dinamicamente

David542

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();
}
tstanisl

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 _Genericna 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 Xpara 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.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

Usando o pré-processador DATE dinamicamente

Usando $ emit para chamar uma função

Usando `SELECT` para chamar uma função

Usando QEventLoop para chamar uma função

Como chamar uma função constexpr de uma diretiva #if do pré-processador?

O que há de mais próximo para chamar uma função Python usando uma versão diferente do Python?

mudar o ponteiro de função externa para ponteiro externo usando o pré-processador

Usando apenas o pré-processador para concatenação de strings?

Como chamar uma função dinamicamente?

O pré-processador concatenado define para formar uma string

Usando a classe Spring StoredProcedure para chamar uma função

usando Gmock para chamar uma função de membro

Encapsular a função usando o pré-processador C11

Quais símbolos de pré-processador o Coverity define para uma construção usando 'cov-build'?

Chamar a função Javascript assim que a tabela for carregada dinamicamente usando uma chamada ajax

Como chamar a função Python por nome dinamicamente usando uma string?

Existe uma maneira de definir dinamicamente os valores das variáveis para a pós-solicitação com o pré-processador jmeter beanshell

Selecione dinamicamente uma função para chamar sem variáveis intermediárias

Programando com php7.0 uma função para chamar procedimentos armazenados mysql dinamicamente

Você não pode chamar uma macro de pré-processador de um namespace específico da mesma maneira que chama uma função de um namespace específico?

Usando avaliação não padrão para chamar um argumento em uma função aninhada

Uma função R para gerar dinamicamente outra função R usando um vetor de caracteres

Usando Promises para chamar uma função dentro de outra função com a biblioteca Bluebird Promises

Usando onclick para chamar uma função de dentro de outra função

Usando ajax para chamar uma função php ao pressionar o botão e atualizar

Como faço para chamar uma função dentro de ajax usando codeigniter para atualizar

Como faço para remover o parâmetro vazio usando o pré-processador de beanshell no jmeter

Como faço para remover o parâmetro vazio usando o pré-processador de beanshell no jmeter

Como usar uma variável de pré-processador dentro de uma função de pré-processador com o Inno Setup