1

Considérez ce qui suit - Je souhaite vérifier avec #if#endif si un jeton est défini quelque part dans le code. J'utilise une macro CONCAT(input) qui doit coller les parties constantes et changeantes du jeton que je veux vérifier.Impossible de résoudre une macro similaire à une fonction dans un bloc de compilation conditionnel

Malheureusement, l'approche présentée provoque ci-dessous une erreur de compilation:

error: missing binary operator before token "("


J'ai trouvé les expressions qui peuvent être mis à l'intérieur d'un bloc #if#endif:

https://gcc.gnu.org/onlinedocs/cpp/If.html#If

Et apparemment, il dit que:

Macros. Toutes les macros de l'expression sont développées avant le début du calcul de la valeur de l'expression.

Il se avère que (CONCAT(test)) devrait être résolu, mais ce n'est pas.

Existe-t-il une solution permettant de résoudre correctement les noms de jetons concaténés dans un bloc de compilation conditionnel?

#include <stdio.h> 

#define CONCAT(input) string##input 
#define stringtest 1 

int main(void) 
{ 
    #if defined(CONCAT(test)) && (CONCAT(test)==1) 
     printf("OK"); 
    #else 
     printf("NOT"); 
    #endif 

    return 0; 
} 
+1

Je pense que vous ne pouvez pas faire cela. – tilz0R

Répondre

2

Si vous utilisez juste: #if CONCAT(test) == 1 il fonctionnera et C'est assez. La déclaration #if defined(CONCAT(test)) ne pas travail parce CONCAT(test) sera évalué à stringtest qui sera évalué à 1, et vous ne pouvez pas utiliser defined sur une constante numérique.

A different situation came to my mind - what if I want to check whether the token is eg. != 1 Then if it is not defined anywhere, the condition will evaluate to true. So there would be no difference between token not defined and token being different than 1.

Vous pouvez gérer == 0égaleto not defined. Donc, vous pouvez utiliser: #if CONCAT(test) != 0 && CONCAT(test) != 1CONCAT(test) != 0 signifie defined(CONCAT(test)). C'est la seule alternative, parce que vous ne pouvez pas obtenir le développement de macro dans une instruction #ifdef ou #if defined(), voir ce question qui est très semblable au vôtre.


Le gcc documentation dit:

Conditionals written like this: #if defined BUFSIZE && BUFSIZE >= 1024

can generally be simplified to just #if BUFSIZE >= 1024 , since if BUFSIZE is not defined, it will be interpreted as having the value zero.

En outre, il peut être utile si vous vérifiez l'expansion macro à l'aide gcc -E yourSource.cpp.

gcc --help:

-E Preprocess only; do not compile, assemble or link

+0

Merci pour la suggestion plus simple. Une situation différente est venue à l'esprit - et si je veux vérifier si le jeton est par exemple. '! = 1' Ensuite, si elle n'est définie nulle part, la condition sera évaluée à true. Il n'y aurait donc pas de différence entre un jeton non défini et un jeton différent de 1. Avez-vous une suggestion pour un tel cas? –

+0

J'ai édité ma réponse pour répondre à votre question supplémentaire, j'espère que cela aide comme une alternative. –

1

Vous ne pouvez pas faire cela. Seuls les littéraux peuvent être utilisés.

Vous devriez vérifier macro directement:

#include <stdio.h> 

#define CONCAT(input) string##input 
#define stringtest 1 

int main(void) { 
    #if stringtest == 1 
     printf("OK"); 
    #else 
     printf("NOT"); 
    #endif 
    return 0; 
} 

Puisque vous ne cochez pas besoin défini, vous pouvez utiliser comme ceci:

#define CONCAT(input) string##input 
#define stringtest 1 

int main(void) { 
    #if CONCAT(test) == 1 
     printf("OK"); 
    #else 
     printf("NOT"); 
    #endif 
    return 0; 
} 
+1

BTW, c'est superflu. '#if stringtest == 1' est suffisant. – ArturFH

+0

Oui, cela suffit, le corrigera. – tilz0R