4
votes

Comment attraper une macro non définie dans la condition du préprocesseur #if?

Sur la base de cette question Comment attraper le vide défini macro avec gcc? J'ai un autre problème. Comment attraper une macro non définie dans la condition du préprocesseur #if ? Exemple de code:

#ifndef ENABLE_SOMETHING
    #error "ENABLE_SOMETHING undefined!"
#endif

Existe-t-il un moyen de détecter une erreur / un avertissement lorsque ENABLE_SOMETHING n'est pas défini à l'aide du compilateur gcc (peut-être un indicateur)? Ou peut-être y a-t-il des outils externes que je peux utiliser?


Je sais que je peux écrire quelque chose comme ceci:

#include <stdio.h> 

int main()
{
#if ENABLE_SOMETHING == 1
    ... do something ..
#endif
 return 0;
}

Mais j'ai un énormément de définitions différentes ( ENABLE_STH1 , ENABLE_STH2 , ENALBE_STH3 ... etc.) dans le code et je ne veux pas résoudre ce problème manuellement . Je recherche une solution automatique pour notre projet.


11 commentaires

Vous obtiendrez une erreur de pré-processeur si la macro n'est pas définie dans l'exemple ci-dessus. Quelque chose comme cette erreur : "MAX_N_LENGTH" non déclaré


Si MAX_N_LENGTH n'est pas défini, le compilateur ne compilera pas le code.


Ok, mon erreur, mauvais exemple. Attendez un moment.


Êtes-vous en train de dire que vous avez des jetons non définis utilisés dans votre code et qu'il est en cours de compilation? Je ne comprends pas cette question.


Oui, j'utilise ces jetons pour activer / désactiver certaines parties de code dans différentes configurations de construction. Mais je veux avoir une certaine garde pour les erreurs futures si quelqu'un fait un nouveau #if mais oublie d'ajouter #define (qui s'est produit).


Après le montage, je ne comprends pas ce que vous demandez. Demandez-vous comment utiliser la recherche et le remplacement dans votre éditeur de texte? Le seul moyen fiable d'obtenir une erreur du compilateur est d'utiliser explicitement #error . Quelle que soit la solution, il n'y a aucun moyen de modifier le code.


Si vous ne voulez pas afficher une erreur mais souhaitez simplement rendre le code robuste, vous pouvez écrire #if défini MAX_N_LENGTH && (MAX_N_LENGTH == 1) .


Ok mais comme je l'ai dit, il y a trop d'endroits à corriger et d'autres programmeurs pourraient ajouter un nouvel endroit et l'ajouter à tort, sans defined () . Je recherche une solution automatique.


L'idée même de la compilation conditionnelle n'est-elle pas que différentes compilations se produisent lorsque différents identificateurs de pré-processeur sont définis ou non? Alors tu ne veux pas ça!


Pourquoi est-ce un problème? Vous fiez-vous à la différence entre ne pas être défini du tout et être défini comme 0 n'importe où?


À cause d'erreurs humaines. La semaine dernière, quelqu'un a ajouté le code #if ENABLE_STH1 == 1 et l'a également ajouté dans le fichier de configuration #ifndef STH1_ENABLE #define STH1_ENABLE 1 #endif Le problème était dû au fait que dans certaines configurations de construction (qui nécessitaient ENABLE_STH == 0 , cela fonctionnait comme prévu. Mais d'autres configurations avaient une erreur qui a été trouvée par un test humain.)


4 Réponses :


0
votes

Supposons que vous ayez ce code et qu'il se compile, mais vous ne savez pas si MAX_N_LENGTH est une macro, ou si c'est autre chose:

#ifdef MAX_N_LENGTH
    printf("MAX_N_LENGTH is a macro.\n");
#else
    printf("MAX_N_LENGTH is NOT macro.\n");
#endif // MAX_N_LENGTH

Vous peut vérifier s'il s'agit bien d'une macro comme celle-ci:

int main()
{
    int a = MAX_N_LENGTH; // MAX_N_LENGTH could also be an int declared somewhere else
    return 0;
}

Bien sûr, si cela pose un problème, je repenserais mes conventions de dénomination.

p>


3 commentaires

Merci pour la question mais j'ai donné un mauvais exemple. Question redéfinie.


La même chose s'applique toujours, vous pouvez utiliser #ifdef ... #endif pour obtenir une compilation conditionnelle selon que la macro en question existe ou non.


OK, ajout d'informations en question. Je connais cette solution mais je recherche une solution automatique.



0
votes

Vous pouvez essayer quelque chose comme ce qui suit:

#ifndef MAX_N_LENGTH
#warning "MAX_N_LENGTH is undefined"
    int array[16];
#else
    int array[MAX_N_LENGTH + 1];
#endif


1 commentaires

Merci pour la question mais j'ai donné un mauvais exemple. Question redéfinie.



0
votes

Vous pouvez tester si une macro est définie dans une expression de préprocesseur #if avec defined(ENABLE_SOMETHING):

#if ENABLE_SOMETHING + 0 == 1
   /* ENABLE_SOMETHING is defined and not 0 or empty */
#endif

Vous pouvez gérer les macros avec une définition vide de cette façon:

#if !defined(ENABLE_SOMETHING)
  #error ENABLE_SOMETHING is not defined
#endif


0 commentaires

4
votes

Existe-t-il un moyen de détecter une erreur / un avertissement lorsque ENABLE_SOMETHING n'est pas défini en utilisant le compilateur gcc (peut-être un drapeau)?

Avec GCC, vous pouvez utiliser l'indicateur -Wundef .

De la documentation officielle

-Wundef

Avertir si un identifiant non défini est évalué dans une directive #if. Ces identifiants sont remplacés par zéro.

EDIT:

Par exemple, ce code C:

$ gcc undef.c -Wundef
undef.c: In function 'main':
undef.c:5:5: warning: "UNDEFINED_MACRO" is not defined [-Wundef]
 #if UNDEFINED_MACRO
     ^

... compilé avec GCC et le drapeau -Wundef donne ceci:

#include <stdio.h>

int main(void)
{
#if UNDEFINED_MACRO
  printf("hi mum!\n");
#endif

  return 0;
}

2 commentaires

Ok, alors -Wundef avec -Werror me donnera une erreur, n'est-ce pas?


@ s.paszko: Oui. -Werror convertit les avertissements en erreurs qui font échouer la compilation, ce qui émettrait une erreur si le compilateur rencontrait une macro non définie