Est-il possible d'utiliser une instruction if dans #define?
Je suis en train de faire une macro avec la formule suivante: (a^2/(a+b))*b
et je veux faire en sorte que la il n'y aura pas de division par zéro.
#define SUM_A( x, y ) if( x == 0 || y == 0) { 0 } else { ( ( ( x * x ) / ( ( x ) + ( y ) ) ) * ( y ) )}
et puis j'ai appeler la macro à l'intérieur:
float a = 40, b = 10, result;
result = SUM_A(a, b);
printf("%f", result);
J'ai essayé d'utiliser des parenthèses autour de la fonction si, mais je continue à faire des erreurs de syntaxe avant de l'instruction if. J'ai aussi essayé d'utiliser le retour, mais j'ai lu quelque part que vous n'êtes pas censé l'utiliser à définir.
source d'informationauteur Frey1337 | 2012-10-20
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser une instruction if, parce que
#define
c'est interpréter par le préprocesseur, et la sortie seraitqui est le problème de la syntaxe.
Mais une alternative est d'utiliser l'opérateur ternaire. Changer vos définir à
N'oubliez pas de toujours mettre vos définir entre parenthèses, pour éviter une erreur de syntaxe lors du remplacement.
if
introduit une déclaration, pas une expression. Utiliser le "ternaire" (conditionnel) opérateur:Sinon, faire un
inline
fonction:Cela évite le problème des multiples d'évaluation de
x
et/ouy
et est beaucoup plus lisible, mais il n'fixer les types dex
ety
. Vous pouvez également déposer leinline
et laisser le compilateur décider si l'in-lining cette fonction est utile (inline
n'est pas une garantie qu'il va effectuer inlining).Techniquement, il est possible d'utiliser
if
déclarations dans un#define
(mais pas de la façon que vous attendez). Depuis#define
s sont juste le texte de substitution, vous devez être très prudent sur la façon dont vous les développez. J'ai trouvé que cela fonctionne...Cela devrait vous donner le résultat que vous recherchez, et il n'y a pas de raison qu'il ne peut pas être étendue pour inclure plusieurs
else if
s (même si comme d'autres réponses l'ont souligné, il est probablement plus facile d'utiliser l'opérateur ternaire).Le problème est que
if
déclaration n'est pas une expression, et ne retourne pas une valeur. En outre, il n'existe aucune bonne raison pour utiliser une macro dans ce cas. En fait, il pourrait causer de très graves problèmes de performances (selon ce que vous transmettez en tant que macro arguments). Vous devez utiliser une fonction à la place.Il y a plusieurs problèmes avec votre macro:
il se développe à une déclaration, de sorte que vous ne pouvez pas l'utiliser comme une expression
les arguments ne sont pas correctement mis entre parenthèses dans l'expansion: en invoquant cette macro avec rien, mais les noms de variables ou de constantes va créer des problèmes.
les arguments sont évalués à plusieurs reprises: si vous appelez de la macro avec des arguments qui ont des effets secondaires, tels que
SUM_A(a(), b())
ouSUM_A(*p++, 2)
du côté de l'effet de se produire plusieurs fois.Pour éviter tous ces problèmes, l'utilisation d'une fonction, éventuellement défini comme
static inline
pour aider le compilateur d'optimiser plus (ceci est facultatif et les compilateurs modernes le font automatiquement):Notes:
OUI, vous pouvez avoir une instruction if dans une macro. Vous devez la formater correctement. Voici un exemple: