En quoi une fonction en ligne diffère-t-elle d'une macro de préprocesseur?
Les macros de préprocesseur ne sont que des modèles de substitution appliqués à votre code. Ils peuvent être utilisés presque n'importe où dans votre code car ils sont remplacés par leurs extensions avant le début de la compilation.
Les fonctions en ligne sont des fonctions réelles dont le corps est directement injecté dans leur site d'appels. Ils ne peuvent être utilisés que lorsqu'un appel de fonction est approprié.
Pour ce qui est de l’utilisation des macros par rapport aux fonctions intégrées dans un contexte semblable à une fonction, sachez que:
Premièrement, les macros du préprocesseur sont simplement "copier/coller" dans le code avant la compilation. Donc, il n'y a pas de vérification de type, et certains effets secondaires peuvent apparaître
Par exemple, si vous souhaitez comparer 2 valeurs:
#define max(a,b) ((a<b)?b:a)
Les effets secondaires apparaissent si vous utilisez par exemple max(a++,b++)
(a
ou b
sera incrémenté deux fois). Au lieu de cela, utilisez (par exemple)
inline int max( int a, int b) { return ((a<b)?b:a); }
Les fonctions Inline sont développées par le compilateur, tandis que les macros sont développées par le préprocesseur, qui est une simple substitution textuelle.
Il n'y a pas de vérification de type lors de l'appel de macro alors que la vérification de type est effectuée lors de l'appel de la fonction.
Des résultats et une inefficacité indésirables peuvent se produire lors de l’expansion de macros en raison de la réévaluation des arguments et de l’ordre des opérations. Par exemple
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int i = 5, j = MAX(i++, 0);
aboutirait à
int i = 5, j = ((i++)>(0) ? (i++) : (0));
Les arguments de la macro ne sont pas évalués avant l'expansion de la macro
#define MUL(a, b) a*b
int main()
{
// The macro is expended as 2 + 3 * 3 + 5, not as 5*8
printf("%d", MUL(2+3, 3+5));
return 0;
}
// Output: 16`
Le mot clé return ne peut pas être utilisé dans les macros pour renvoyer des valeurs comme dans le cas de fonctions.
Les fonctions en ligne peuvent être surchargées
Les jetons transmis aux macros peuvent être concaténés à l'aide de l'opérateur ## appelé opérateur de jeton.
Les macros sont généralement utilisées pour la réutilisation de code lorsque les fonctions inline sont utilisées pour éliminer le temps système (temps supplémentaire) au cours de l'appel de la fonction (en évitant le passage à un sous-programme).
La principale différence est la vérification de type. Le compilateur vérifiera si les valeurs que vous transmettez en tant que valeurs d'entrée peuvent être transmises à la fonction. Ce n'est pas vrai avec les macros de préprocesseur - elles sont développées avant toute vérification de type et cela peut causer des bogues graves et difficiles à détecter.
Ici Plusieurs autres points moins évidents sont décrits.
Pour ajouter une autre différence à celles déjà données: vous ne pouvez pas parcourir un #define
dans le débogueur, mais vous pouvez parcourir une fonction en ligne.
Les macros ignorent les espaces de noms. Et cela les rend méchants.
les fonctions inline sont similaires aux macros (car le code de la fonction est développé au moment de l'appel lors de la compilation), les fonctions inline sont analysées par le compilateur, alors que les macros sont développées par le préprocesseur. En conséquence, il existe plusieurs différences importantes:
Dans certains cas, les expressions passées comme arguments à des macros peuvent être évaluées plusieurs fois. http://msdn.Microsoft.com/en-us/library/bf6bf4cf.aspx
les macros sont développées au moment de la pré-compilation, vous ne pouvez pas les utiliser pour le débogage, mais vous pouvez utiliser des fonctions inline.
- bon article : http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1 =
;
Une fonction en ligne conservera la sémantique des valeurs, alors qu'une macro de préprocesseur ne fera que copier la syntaxe. Vous pouvez obtenir des bogues très subtils avec une macro de préprocesseur si vous utilisez l'argument plusieurs fois - par exemple, si l'argument contient une mutation telle que "i ++", le fait de l'exécuter deux fois est assez surprenant. Une fonction en ligne n'aura pas ce problème.
Une fonction inline se comporte syntaxiquement comme une fonction normale, offrant une sécurité de type et une portée pour les variables locales de la fonction et un accès aux membres de classe s'il s'agit d'une méthode. De même, lorsque vous appelez des méthodes en ligne, vous devez vous conformer aux restrictions privées/protégées.
Du point de vue du codage, une fonction en ligne est comme une fonction. Ainsi, les différences entre une fonction en ligne et une macro sont identiques à celles entre une fonction et une macro.
Du point de vue de la compilation, une fonction en ligne est similaire à une macro. Il est injecté directement dans le code, pas appelé.
En général, vous devriez considérer les fonctions inline comme des fonctions régulières avec une optimisation mineure mélangée. Et comme la plupart des optimisations, il appartient au compilateur de décider s’il est vraiment intéressé à l’appliquer. Souvent, le compilateur ignorera volontiers les tentatives du programmeur pour intégrer une fonction, pour diverses raisons.
les fonctions en ligne se comporteront comme un appel de fonction s’il existe une instruction itérative ou récursive, afin d’empêcher l’exécution répétée d’instructions. C'est très utile pour sauvegarder la mémoire globale de votre programme.
En GCC (je ne suis pas sûr des autres), déclarer une fonction inline est juste un indice pour le compilateur. Il appartient toujours au compilateur en fin de journée de décider si elle inclut ou non le corps de la fonction à chaque appel.
La différence entre les fonctions en ligne et les macros de préprocesseur est relativement grande. Les macros de préprocesseur ne sont que du remplacement de texte à la fin de la journée. Vous donnez beaucoup de possibilités au compilateur de vérifier le type des arguments et du type de retour. L'évaluation des arguments est très différente (si les expressions que vous passez dans les fonctions ont des effets secondaires, le débogage sera très amusant). Il existe des différences subtiles quant à l’utilisation des fonctions et des macros. Par exemple si j'avais:
#define MACRO_FUNC(X) ...
Où MACRO_FUNC définit évidemment le corps de la fonction. Des précautions particulières doivent être prises pour qu’elle fonctionne correctement dans tous les cas. Une fonction peut être utilisée. Par exemple, un MACRO_FUNC mal écrit causerait une erreur
if(MACRO_FUNC(y)) {
...body
}
Une fonction normale pourrait être utilisée sans problème ici.