web-dev-qa-db-fra.com

Macros de fonction vides

Si je définis une macro de fonction sans corps réel, est-ce comme une chaîne vide avec le compilateur (c'est-à-dire qu'elle ne génère aucune instruction supplémentaire au moment de la compilation)?

Exemple:

#define SomeMacro(a)

SomeMacro("hello"); // This line doesn't add any instructions, does it?

Vous avez absolument raison, la macro vide ne génère aucun code.

J'ai vu deux endroits où cela est utile. La première consiste à éliminer les avertissements lorsqu'un paramètre de fonction n'est pas utilisé:

#define UNUSED(x)

int foo(int UNUSED(value))
{
    return 42;
}

La seconde est lorsque vous utilisez des conditions pour déterminer s'il doit y avoir du code ou non.

#ifdef LOGGING_ENABLED
#define LOG(x) log_message(x)
#else
#define LOG(x)
#endif
48
Mark Ransom

Votre code n'est pas totalement correct, je vous suggère de mettre des accolades vides dans votre macro

#define somemacro(a) {}

la raison est simple, votre code sera beaucoup plus sûr!

prenez cet exemple:

if(Value)
    somemacro(a)
else
    somemacro(b)

Si la macro est vide, votre code ne se compilera pas! (Expression primaire attendue avant "else"). Quoi qu'il en soit, certaines règles de style vous obligent à écrire

if(Value)
{
    somemacro(a)
}
else
{
    somemacro(a)
}

ce ne sera donc pas un problème.

Une autre option consiste à utiliser ";" au lieu de "{}" mais cette option dans le même cas vous donnera des avertissements de temps de compilation, tandis que les accolades vides ne donneront ni avertissements ni erreurs! (le point-virgule est encore meilleur même s'il donne des avertissements);)

prendre le cas suivant

if(value)
    somemacro(a);
else
    somemacro(b);

va s'étendre à

if(value)
{};
else
{};

qui ne peut pas compiler!

Voilà pourquoi les macros sont mauvaises

(Étant donné que les macros sont un simple remplacement de texte, la règle des idiots devrait être de toujours essayer de remplacer manuellement le code et de voir ce qui se passe, il existe également des outils qui remplaceront les macros pour vous montrer le code développé.)

Toujours deviner s'il y a une macro qui est totalement sûre? Oui, cela s'appelle "NOP"

#define somemacro(a) ((void)0)

cela fonctionnera dans tous les cas (même les fichiers source des compilateurs l'utilisent comme NOP, par exemple il suffit de regarder "assert.h"

19
CoffeDeveloper

Le préprocesseur effectue une substitution littérale avec toutes les macros.

Par conséquent, si vous définissez une macro "vide", chaque emplacement dont l'identifiant apparaît dans votre code sera remplacé par une instruction vide par le préprocesseur avant l'exécution du compilateur.

Donc oui. Aucun code ne sera généré pour l'exemple donné dans votre question.

6
Cody Gray

C'est correct. Votre code s'étend à

;

après prétraitement.

Notez que vous pouvez demander à votre compilateur de vous montrer le code après prétraitement (en gcc, c'est le -E option; votre compilateur peut varier).

6
Greg Hewgill