Je lisais un certain code écrit en C ce soir et au sommet de
Le fichier était le cas de la macro de forme de fonction: Cela m'a laissé me demander, pourquoi quelqu'un choisirait-il de mettre en œuvre un
fonctionner de cette façon en utilisant une macro en forme de fonction au lieu de la mise en œuvre
c'est comme une fonction de vanille régulière? Quels sont les avantages et
Inconvénients de chaque mise en œuvre? P> Merci un tas! p> p>
6 Réponses :
D'une part, les macros sont mauvaises parce qu'elles sont faites par le préprocesseur, ce qui ne comprend rien sur la langue et remplace Text-Remplacer. Ils ont généralement beaucoup de limitations. Je ne peux pas voir un ci-dessus, mais généralement les macros sont des solutions laides. P>
D'autre part, ils sont parfois encore plus rapides qu'un méthode statique en ligne code>. J'épaume fortement un programme court et j'ai constaté que l'appelant à une méthode code> statique code> prend environ deux fois plus de temps (juste en tête, pas le corps de fonction réel) par rapport à une macro. P>
C'est bon à savoir. Merci! Juste curieux, quel outil utilisiez-vous pour optimiser votre code C? Je n'ai pas essayé d'optimisation auparavant et je voudrais essayer d'essayer.
Outil? Vim, GProf code> et la commande vénérable
la commande code>.
GPROF CODE> est un très bon profileur avec des frais généraux faibles, bien que vous devez faire attention car il ne suit pas les macros (cela ne les voit pas; une autre des réciprides de Macros).
Quelle version utilisait votre compilateur et quel niveau d'optimisation demandez-vous de votre demander?
GCC version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) code> (g ++). L'optimisation était
-O3 code>.
Le C Préprocesseur peut être utilisé pour créer des fonctions en ligne. Dans votre exemple, le code semble appeler le hachage de fonction, mais il ne s'agit que d'un code en ligne. P>
Les avantages de faire des fonctions macro ont été éliminés lorsque C ++ introduit des fonctions en ligne. Beaucoup d'apeses plus anciennes comme MFC et ATL utilisent toujours des fonctions de macro pour faire des astuces de préprocesseur, mais cela laisse simplement le code compliqué et plus difficile à lire. P>
Votre exemple n'est pas vraiment une fonction du tout,
int hashThis(int fp) { return ((fp)%NHASH); }
macros comme celui-ci éviter la surcharge d'un appel de la fonction. P>
Cela pourrait ne pas sembler beaucoup. Mais dans votre exemple, la macro se transforme en 1-2 instructions de langue de la machine, en fonction de votre CPU: p>
alors que l'équivalent de fonction serait beaucoup plus d'instructions sur la langue de la machine, généralement quelque chose comme p>
beaucoup plus de code, hein? Si vous faites quelque chose comme rendant chacun des dizaines de milliers de pixels dans une fenêtre dans une interface graphique, les choses gèrent beaucoup plus rapidement si vous utilisez la macro. P>
Personnellement, je préfère utiliser C ++ en ligne comme étant plus lisible et moins sujette d'erreur, mais les inlines sont également vraiment plus un indice au compilateur qu'il n'a pas à prendre. Les macros de préprocesseur sont un marteau de luge que le compilateur ne peut pas discuter avec. P>
WOW, vous avez raison, c'est bien plus de code pour la mettre en œuvre en tant que fonction!
C'est ce que les fonctions en ligne sont pour! :)
Liranuna: Les fonctions en ligne ne font pas partie de l'ANSI C90, ce que la plupart des compilateurs soutiennent. Ils sont seulement en C99, ou C ++
Certains compilateurs le soutiennent comme une extension, cependant.
C99 est, bien sûr, de dix ans maintenant. Tout compilateur C qui ne le supporte pas est sérieusement obsolète.
@ liw.fi: dites-le à Microsoft!
BTW ... Modulo est un enfer de beaucoup plus de 1 instruction sur chaque processeur.
@Goz: Les instructions DIV et DIVU 68000 DIVS font un quotient et un reste de 16 bits simultanés, et le 68020 s'étend sur 32 bits.
@Goz: En outre, les instructions X86 DIV et VIDIV font un quotient simultané de 8, 16 ou 32 bits et du reste (modulo). Cependant, cela me semble que comme ARM CPUS ne calcule pas le reste comme une seule opération de la machine.
Les raisons les plus courantes (et la plus souvent erronées) Les personnes donnent pour l'utilisation de macros (dans "l'ancien clair C") sont l'argument d'efficacité. L'utilisation d'une efficacité est bonne si vous avez profilé votre code et optimise un véritable goulot d'étranglement (ou écrivez une fonction de bibliothèque qui pourrait être un goulot d'étranglement pour quelqu'un un jour). Mais la plupart des gens qui insistent sur l'utilisation de leur utilisation n'ont rien analysé et ne créent que de la confusion là où elle n'ajoute aucun avantage. p>
Les macros peuvent également être utilisées pour des substitutions de type de recherche et de remplacement pratiques que le langage C normal C n'est pas capable. p>
Certains problèmes que j'ai eu pour maintenir le code écrit par des agresseurs macro-abuseurs sont que les macros peuvent ressembler à des fonctions, mais ne figurent pas dans la table des symboles, il peut donc être très gênant d'essayer de les retracer dans leurs origines Codes (où est-ce que cette chose est définie ?!). L'écriture de macros dans toutes les capsules est évidemment utile pour les futurs lecteurs. p>
S'ils sont plus que des substitutions assez simples, elles peuvent également créer une certaine confusion si vous devez passer à autre chose avec un débogueur. p>
Pourriez-vous donner un exemple d'une de ces substitutions de recherche et de remplacement qui ne peuvent être effectuées que avec des macros que vous parlez?
Lignes génératrices de code comme: #define colorval (couleur, val) int couleur ## _ Number = val; Je ne ferais pas cela moi-même trop, mais si vous avez besoin de lignes pour rouge, bleu, vert, ..., noir, alors cela peut aider.
p.212 du "Manuel de l'UNIX HATER" (p.248 dans le fichier .pdf SIMSON.net/ ref / ugh.pdf , de CS.Washington.edu /homes/weise/uhh-download.html ) discute de certaines difficultés connexes.
Un avantage important de la mise en oeuvre macro-macro est qu'il n'est pas lié à un type de paramètre concret. Une macro en forme de fonction dans C agit, à de nombreux égards, comme une fonction de modèle en C ++ (les modèles de C ++ sont nés de macros "plus civilisés", BTW). Dans ce cas particulier, l'argument de la macro n'a pas de type concret. Cela pourrait être absolument tout ce qui est convertible en type Quoi qu'il en soit, je dois admettre que cette macro n'est pas le meilleur exemple de Flexibilité indépendante des macros, mais en général, la flexibilité est très souvent pratique. Encore une fois, lorsque certaines fonctionnalités sont implémentées par une fonction, il est limité à des types de paramètres spécifiques. Dans de nombreux cas, afin d'appliquer une opération similaire à différents types, il est nécessaire de fournir plusieurs fonctions avec différents types de paramètres (et des noms différents, car cela est c), tandis que la même chose peut être effectuée par une macro à une seule fonction. Par exemple, MACRO P> non signé long code>. Par exemple, si l'utilisateur plaît, si l'utilisateur plaît (et s'ils sont disposés à accepter les conséquences définies par la mise en œuvre), ils peuvent transmettre des types de pointeur à cette macro.
#define ABS(x) ((x) >= 0 ? (x) : -(x))
Au fur et à mesure que les fonctions de hasch vont, c'est assez faible - mais alors, il semble que les données à traiter soient aussi simples.
En fait, il n'est pas très lumineux de faire en sorte que cela a un
macro code>. Fonction statique en ligne est probablement plus appropriée. C I> a eu une inine depuis 1999 et
GCC code> même avant cela. Cette question a été citée comme duplicate Utilisation KFIFO de Définitions A >. Si MS-Windows B> est la raison pour laquelle les personnes disent que cette macro est raisonnable, comment sont-elles liées?