Inline-functies versus Preprocessor-macro’s

Hoe verschilt een inline-functie van een preprocessor-macro?


Antwoord 1, autoriteit 100%

Preprocessor-macro’s zijn slechts vervangingspatronen die op uw code worden toegepast. Ze kunnen bijna overal in uw code worden gebruikt, omdat ze worden vervangen door hun uitbreidingen voordat de compilatie begint.

Inline-functies zijn feitelijke functies waarvan het lichaam rechtstreeks in hun oproepplaats wordt geïnjecteerd. Ze kunnen alleen worden gebruikt waar een functieaanroep van toepassing is.

Wat betreft het gebruik van macro’s versus inline-functies in een functie-achtige context, houd er rekening mee dat:

  • Macro’s zijn niet typeveilig en kunnen worden uitgebreid, ongeacht of ze syntactisch correct zijn – de compileerfase zal fouten rapporteren die het gevolg zijn van macro-uitbreidingsproblemen.
  • Macro’s kunnen worden gebruikt in een context waar je het niet verwacht, wat tot problemen leidt
  • Macro’s zijn flexibeler, omdat ze andere macro’s kunnen uitbreiden, terwijl inline-functies dit niet noodzakelijkerwijs doen.
  • Macro’s kunnen bijwerkingen veroorzaken vanwege hun uitbreiding, aangezien de invoeruitdrukkingen worden gekopieerd waar ze ook in het patroon voorkomen.
  • Inline-functies zijn niet altijd gegarandeerd inline – sommige compilers doen dit alleen in release-builds, of wanneer ze specifiek zijn geconfigureerd om dit te doen. In sommige gevallen is inlining ook niet mogelijk.
  • Inline-functies kunnen ruimte bieden voor variabelen (met name statische), preprocessor-macro’s kunnen dit alleen in codeblokken {…} en statische variabelen gedragen zich niet precies hetzelfde.

Antwoord 2, autoriteit 59%

Ten eerste zijn de preprocessor-macro’s gewoon “kopiëren en plakken” in de code vóór de compilatie. Er is dus geen typecontroleen er kunnen enkele bijwerkingenoptreden

Als u bijvoorbeeld 2 waarden wilt vergelijken:

#define max(a,b) ((a<b)?b:a)

De bijwerkingen treden op als u bijvoorbeeld max(a++,b++)gebruikt (aof bwordt twee keer verhoogd).
Gebruik in plaats daarvan (bijvoorbeeld)

inline int max( int a, int b) { return ((a<b)?b:a); }

Antwoord 3, autoriteit 12%

De inline-functies worden uitgebreid door de compiler, terwijl de macro’s worden uitgebreid door de preprocessor, wat slechts een tekstuele vervanging is.

Vandaar,

  • Er is geen typecontrole tijdens het aanroepen van macro’s terwijl typecontrole wordt uitgevoerd tijdens functieaanroep.

  • Ongewenste resultaten en inefficiëntie kunnen optreden tijdens macro-uitbreiding als gevolg van herevaluatie van argumenten en volgorde van bewerkingen. Bijvoorbeeld:

    #define MAX(a,b) ((a)>(b) ? (a) : (b))
    int i = 5, j = MAX(i++, 0);
    

    zou resulteren in

    int i = 5, j = ((i++)>(0) ? (i++) : (0));
    
  • De macro-argumenten worden niet geëvalueerd vóór de macro-uitbreiding

    #include <stdio.h>
     #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
    
  • Het return-sleutelwoord kan niet in macro’s worden gebruikt om waarden te retourneren, zoals in het geval van functies.

  • Inline-functies kunnen overbelast raken.

  • De tokens die aan macro’s worden doorgegeven, kunnen worden samengevoegd met de operator ##, de operator Token-Pasting.

  • Macro’s worden over het algemeen gebruikt voor hergebruik van code, waarbij inline-functies worden gebruikt om de overhead (overtollige tijd) tijdens functieaanroep te elimineren (waardoor een sprong naar een subroutine wordt vermeden).


Antwoord 4, autoriteit 9%

Het belangrijkste verschil is typecontrole. De compiler controleert of wat u als invoerwaarden doorgeeft, van het type is dat aan de functie kan worden doorgegeven. Dat is niet het geval met preprocessor-macro’s – ze worden uitgebreid voorafgaand aan elke typecontrole en dat kan ernstige en moeilijk te detecteren bugs veroorzaken.

Hierzijn verschillende andere minder voor de hand liggende punten geschetst.


Antwoord 5, autoriteit 9%

Om nog een verschil toe te voegen aan de reeds gegeven: je kunt niet door een #definestappen in de debugger, maar je kunt wel door een inline-functie stappen.


Antwoord 6, autoriteit 6%

Macro’s negeren naamruimten. En dat maakt ze slecht.


Antwoord 7, autoriteit 2%

inline-functies zijn vergelijkbaar met macro’s (omdat de functiecode wordt uitgebreid op het moment van de aanroep tijdens het compileren), inline-functies worden ontleed door de compiler, terwijl macro’s worden uitgebreid door de preprocessor. Als gevolg hiervan zijn er een aantal belangrijke verschillen:

  • Inline-functies volgen alle protocollen van typeveiligheid die gelden voor normale functies.
  • Inline-functies worden gespecificeerd met dezelfde syntaxis als elke andere functie, behalve dat ze het inline-sleutelwoord in de functiedeclaratie opnemen.
  • Uitdrukkingen die als argumenten aan inline-functies worden doorgegeven, worden één keer geëvalueerd.
  • In sommige gevallen kunnen expressies die als argumenten aan macro’s worden doorgegeven, meer dan eens worden geëvalueerd.
    http://msdn.microsoft.com/en-us/library/bf6bf4cf. aspx

  • Macro’s worden uitgebreid tijdens het compileren, u kunt ze niet gebruiken voor foutopsporing, maar u kunt wel inline-functies gebruiken.

goed artikel:
http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1

;


Antwoord 8

Een inline-functie behoudt de waardesemantiek, terwijl een preprocessor-macro alleen de syntaxis kopieert. Je kunt heel subtiele bugs krijgen met een preprocessor-macro als je het argument meerdere keren gebruikt – als het argument bijvoorbeeld een mutatie zoals “i++” bevat, is het nogal een verrassing om dat twee keer uit te voeren. Een inline-functie heeft dit probleem niet.


Antwoord 9

Om het verschil tussen macro’s en inline-functieste kennen, moeten we eerst weten wat ze precies zijn en wanneer we ze moeten gebruiken.

FUNCTIES:

int Square(int x)
{
    return(x*x);
}
int main()
{
    int value = 5;
    int result = Square(value);
    cout << result << endl;
}
  • Functie-aanroepen hebben overhead met zich mee. Nadat de functie is uitgevoerd, moet hij weten waar hij naar moet terugkeren, dus slaat hij het retouradres op de stapel op voordat de functie wordt aangeroepen. Voor kleine applicaties is dit misschien geen probleem, maar in bijvoorbeeld een financiële applicatie, waar duizenden transacties per seconde plaatsvinden, kan een functieaanroep te duur zijn.

MACROS:

# define Square(x) x*x;
int main()
{
    int value = 5;
    int result = Square(value);
    cout << result << endl;
}
  • Macro’s worden toegepast in de voorbewerkingsfase. Tijdens deze fase worden de statements die zijn geschreven met #definetrefwoorden vervangen of uitgebreid

int resultaat = Vierkant(x*x)

Maar macro’s kunnen onverwacht gedrag veroorzaken.

#define Square(x) x*x
int main()
{
    int val = 5;
    int result = Square(val + 1);
    cout << result << endl;
}

Hier is de uitvoer 11, niet 36.

INLINE FUNCTIES:

inline int Square(int x)
{
    return x * x;
}
int main()
{
    int val = 5;
    int result = Square(val + 1);
    cout << result << endl;
}

Uitvoer: 36

Het inlinetrefwoord verzoekt de compiler om de functieaanroep te vervangen door de hoofdtekst van de functie. Hier is de uitvoer correct omdat deze eerst de uitdrukking evalueert en vervolgens het resultaat gebruikt om de hoofdtekst van de functie uit te voeren. Inline-functies verminderen de overhead van de functie-aanroep omdat het niet nodig is om een ​​retouradres of functieargumenten in de stapel op te slaan.

Vergelijking tussen macro’s en inline-functies:

  1. Macro’s werken door middel van tekstvervanging, terwijl inline-functies de logica van een functie dupliceren.
  2. Macro’s zijn foutgevoelig vanwege vervanging, terwijl inline-functies veilig te gebruiken zijn.
  3. Macro’s kunnen niet worden toegewezen aan functiewijzers; inline-functies kunnen.
  4. Macro’s zijn moeilijk te gebruiken met meerdere regels code, terwijl inline-functies dat niet zijn.
  5. In C++ kunnen macro’s niet worden gebruikt met lidfuncties, terwijl inline-functies dat wel kunnen zijn.

CONCLUSIE:

Inline-functies zijn soms nuttiger dan macro’s, omdat ze veilig te gebruiken zijn, maar ook de overhead van functieaanroepen kunnen verminderen.
Het inlinesleutelwoord is een verzoekaan de compiler, bepaalde functies zullen niet inline zijn zoals:

  • grote functies
  • functies met te veel voorwaardelijke argumenten
  • recursieve code en code met lussen enz.

wat een goede zaak is, omdat het de compiler in staat stelt te bepalen of het beter is om dingen op een andere manier te doen.


Antwoord 10

Een inline-functie gedraagt ​​zich syntactisch net als een normale functie, en biedt typeveiligheid en ruimte voor functie-lokale variabelen en toegang tot klasseleden als het een methode is.
Ook bij het aanroepen van inline-methoden moet u zich houden aan persoonlijke/beschermde beperkingen.


Antwoord 11

In GCC (ik weet het niet zeker van anderen), is het inline declareren van een functie slechts een hint voor de compiler. Het is aan het eind van de dag nog steeds aan de compiler om te beslissen of het de hoofdtekst van de functie bevat wanneer deze wordt aangeroepen.

Het verschil tussen in-line functies en preprocessor-macro’s is relatief groot. Preprocessor-macro’s zijn uiteindelijk slechts tekstvervanging. Je geeft een groot deel van de mogelijkheid voor de compiler op om typecontrole uit te voeren op de argumenten en het retourtype. Evaluatie van de argumenten is heel anders (als de uitdrukkingen die u in de functies doorgeeft neveneffecten hebben, zult u veel plezier beleven aan het debuggen). Er zijn subtiele verschillen over waar functies en macro’s kunnen worden gebruikt. Als ik bijvoorbeeld had:

#define MACRO_FUNC(X) ...

Waarbij MACRO_FUNC duidelijk de hoofdtekst van de functie definieert. Er moet speciale aandacht worden besteed aan het correct werken in alle gevallen dat een functie kan worden gebruikt, bijvoorbeeld een slecht geschreven MACRO_FUNC zou een fout veroorzaken in

if(MACRO_FUNC(y)) {
 ...body
}

Een normale functie kan daar zonder problemen worden gebruikt.


Antwoord 12

Vanuit het perspectief van codering is een inline-functie als een functie. De verschillen tussen een inline-functie en een macro zijn dus hetzelfde als de verschillen tussen een functie en een macro.

Vanuit het perspectief van compileren is een inline-functie vergelijkbaar met een macro. Het wordt rechtstreeks in de code geïnjecteerd, niet aangeroepen.

Over het algemeen zou je inline-functies moeten beschouwen als normale functies met wat kleine optimalisaties erin verwerkt. En zoals bij de meeste optimalisaties, is het aan de compiler om te beslissen of hij het daadwerkelijk wil toepassen. Vaak negeert de compiler alle pogingen van de programmeur om een ​​functie inline te plaatsen, om verschillende redenen.


Antwoord 13

inline-functies zullen zich gedragen als een functie-aanroep als er een iteratieve of recursieve instructie in bestaat, om herhaalde uitvoering van instructies te voorkomen. Het is heel handig om het algemene geheugen van uw programma op te slaan.


Antwoord 14

#include<iostream>
using namespace std;
#define NUMBER 10 //macros are preprocessed while functions are not.
int number()
{ 
    return 10;
}
/*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases. 
However, this is not the case with functions.
Also, macros do not check for compilation error (if any). Consider:- */
#define CUBE(b) b*b*b
int cube(int a)
{
 return a*a*a;
}
int main()
{
 cout<<NUMBER<<endl<<number()<<endl;
 cout<<CUBE(1+3); //Unexpected output 10
 cout<<endl<<cube(1+3);// As expected 64
 return 0;
}

Macro’s zijn meestal sneller dan functies omdat ze geen daadwerkelijke functie-oproep overhead hebben.

Enkele nadelen van macro’s:
Er is geen typecontrole.Diffochen om te debuggen, omdat ze eenvoudige vervanging veroorzaken.macro heeft geen naamruimte, dus een macro in één gedeelte van de code kan een andere sectie beïnvloeden. Macro’s kunnen bijwerkingen veroorzaken zoals weergegeven in bovenstaande kubus () voorbeeld.

Macro’s zijn meestal één voering. Ze kunnen echter uit meer dan één regel bestaan. Er zijn geen dergelijke beperkingen in de functies.

Other episodes