0

J'ai une macro où je passe un argument et l'utilisation qui définissent une nouvelle variable en fonction du nom de l'entrée:Remplacer une chaîne dans une variable macro?

#define DO_X(x) char _do_x_var_ ## x; /* other things */ 

Le problème est que si je passe dans une variable struct, il se casse:

DO_X(some_struct->thing) 

devient:

char _do_x_var_some_struct->thing; /* other things */ 

EDIT: ce que je veux évaluer à est:

char _do_x_var_some_struct__thing; /* other things */ 

(ou tout autre nom de variable valide contenant quelque chose de similaire à l'entrée)

Ce que je veux vraiment est pour ces au travail:

#define DO_X(x) for(char _do_x_var_ ## x; /*things*/) 
DO_X(x){ 
    DO_X(y) { 
     /*things*/ 
    } 
} 

DO_X(object->x){ 
    DO_X(object->y) { 
     /*things*/ 
    } 
} 

mais pour ceux-ci à l'échec:

#define DO_X(x) for(char _do_x_var_ ## x; /*things*/) 
DO_X(x){ 
    DO_X(x) { // <-- multiple definition of _do_x_var_x 
     /*things*/ 
    } 
} 

DO_X(object->x){ 
    DO_X(object->x) { // <-- multiple definition of _do_x_var_object__x (or whatever) 
     /*things*/ 
    } 
} 

Existe-t-il un moyen de faire en sorte que cela fonctionne? Peut-être remplacer -> avec __ ou quelque chose? J'ai trouvé des façons de concaténer, mais pas de remplacer les chaînes.

+0

Pouvez-vous clarifier ce que vous voulez que la macro vous donne? –

+0

1. Essayez-vous de déclarer une variable de classe en dehors de celle-ci? 2. Ceci est la mort par les macros. –

+0

@Oli Charlesworth: J'ai ajouté plus de clarification de ce que je veux –

Répondre

4

Vous n'avez pas trouvé un moyen de réécrire des chaînes arbitraires, car les macros ne peuvent pas le faire. Les noms de macros doivent être des identifiants valides, ce qui n'est pas le cas pour ->. Le préprocesseur C est très limité dans ce qu'il peut faire. Vous pourriez regarder dans m4 pour un préprocesseur plus fort, mais vous êtes probablement dirigé sur la mauvaise route.

2

Je ne connais aucun mécanisme de préprocesseur pour traiter un paramètre struct-> element comme deux jetons séparés ou pour convertir automatiquement le caractère -> en caractère de soulignement. Ma suggestion est d'avoir une macro séparée, par ex. DO_X2 (struct_ptr, element), qui ajouterait "->" ou "_" si nécessaire. Ensuite, vous pouvez utiliser DO_X ou DO_X2 selon le cas.

Il existe un problème distinct si vous envisagez d'utiliser ces macros comme indiqué. La boucle for interne peut déclarer exactement le même nom de variable et ne sera pas considéré comme une erreur, car ils ont une portée différente. Par exemple, en supposant que votre compilateur C prend en charge les déclarer l'itérateur dans le pour déclaration comme celle (que je ne crois pas un comportement standard pour C):

for (int i=0; i<10; ++i) 

Ensuite, vous pouvez faire ce qui suit et il ne serait pas considéré comme une erreur:

int sum = 0; 
for (int i=0; i<10; ++i) 
    for (int i=0; i<10; ++i) 
     ++sum; 

Les deux "int i" ont une portée différente et devraient donc être compilés et exécutés correctement.

Questions connexes