Inline-Funktionen vs. Präprozessor-Makros

Lesezeit: 5 Minuten

Inline Funktionen vs Praprozessor Makros
Subodh

Wie unterscheidet sich eine Inline-Funktion von einem Präprozessor-Makro?

Inline Funktionen vs Praprozessor Makros
LBuschkin

Präprozessormakros sind nur Ersetzungsmuster, die auf Ihren Code angewendet werden. Sie können fast überall in Ihrem Code verwendet werden, da sie durch ihre Erweiterungen ersetzt werden, bevor eine Kompilierung beginnt.

Inline-Funktionen sind eigentliche Funktionen, deren Text direkt in ihre Aufrufseite eingefügt wird. Sie können nur dort verwendet werden, wo ein Funktionsaufruf angebracht ist.

Was nun die Verwendung von Makros vs. Inline-Funktionen in einem funktionsähnlichen Kontext betrifft, sei darauf hingewiesen, dass:

  • Makros sind nicht typsicher und können erweitert werden, unabhängig davon, ob sie syntaktisch korrekt sind – die Kompilierungsphase meldet Fehler, die sich aus Problemen bei der Makroerweiterung ergeben.
  • Makros können in einem Kontext verwendet werden, in dem Sie es nicht erwarten, was zu Problemen führt
  • Makros sind flexibler, da sie andere Makros erweitern können – während Inline-Funktionen dies nicht unbedingt tun.
  • Makros können aufgrund ihrer Erweiterung zu Seiteneffekten führen, da die Eingabeausdrücke kopiert werden, wo immer sie im Muster erscheinen.
  • Inline-Funktionen sind nicht immer garantiert – einige Compiler tun dies nur in Release-Builds oder wenn sie speziell dafür konfiguriert sind. Außerdem ist Inlining in einigen Fällen möglicherweise nicht möglich.
  • Inline-Funktionen können einen Bereich für Variablen bereitstellen (insbesondere statische), Präprozessormakros können dies nur in Codeblöcken {…} tun, und statische Variablen verhalten sich nicht genau so.

  • Inline-Funktionen sind nicht immer garantiert inline: Da der Compiler nicht inline wird, wenn dies langsameren Code usw. generiert. Der Compiler führt viele Analysen durch, die der Ingenieur nicht kann, und tut das Richtige.

    – Martin York

    16. Juli 2009 um 16:20 Uhr

  • Ich glaube, dass rekursive Funktionen ein weiteres Beispiel sind, bei dem die meisten Compiler Inlining ignorieren.

    – LBuschkin

    16. Juli 2009 um 17:57 Uhr

  • Gibt es in diesem Fall wichtige Unterschiede in C im Vergleich zu C++?

    – rzetterberg

    13. September 2011 um 17:22 Uhr

  • Ein nicht erwähnter Punkt ist, dass Inlining durch Kompilierungsflags beeinflusst werden kann. Wenn Sie zum Beispiel für maximale Geschwindigkeit bauen (wie GCC -O2/-O3), entscheidet sich der Compiler dafür, viele Funktionen einzubetten, aber wenn Sie für minimale Größe (-Os) bauen, wird er normalerweise nur einmal aufgerufene Funktionen (oder sehr kleine Funktionen) einbetten ). Bei Makros gibt es diese Wahl nicht.

    – dbrank0

    14. November 2012 um 8:56 Uhr

  • Makros können nicht mit Zugriffsbezeichnern (wie privat oder geschützt) abgedeckt werden, während Inline-Funktionen möglich sind.

    – Treffer

    9. Juli 2014 um 17:25 Uhr

Erstens sind die Präprozessor-Makros vor der Kompilierung nur “Kopieren und Einfügen” in den Code. Es gibt also keine Typprüfungund einige Nebenwirkungen erscheinen kann

Wenn Sie beispielsweise 2 Werte vergleichen möchten:

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

Die Nebenwirkungen treten auf, wenn Sie verwenden max(a++,b++) zum Beispiel (a oder b wird zweimal hochgezählt). Verwenden Sie stattdessen (zum Beispiel)

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

  • Ich möchte Ihrem Beispiel nur hinzufügen, dass Makros neben Nebeneffekten auch zusätzliche Arbeitslast verursachen können max(fibonacci(100), factorial(10000)) der größere wird doppelt berechnet 🙁

    – watashiSHUN

    31. Dezember 2017 um 4:32 Uhr

  • Jeder spricht über Type Checking, aber Sie haben nur ein Beispiel aus der Praxis gegeben, deshalb stimme ich dieser Antwort zu.

    Benutzer2188550

    1. Juni 2020 um 17:19 Uhr

  • @watashiSHUN Warum sollte der größere zweimal berechnet werden? Vielen Dank im Voraus!

    – Mailand

    30. Juli 2021 um 16:28 Uhr

  • Im Makro Warum wird a oder b doppelt erhöht werden? Es ist, weil die max(a++, b++) wird durch ersetzt (a++ < b++) ? b++ : a++, Korrekt? Ich denke, das beantwortet auch meine obige Frage (in Bezug auf den Kommentar von @watashiSHUN). Vielen Dank im Voraus!

    – Mailand

    30. Juli 2021 um 16:53 Uhr


1646956818 325 Inline Funktionen vs Praprozessor Makros
DataCruncher

Die Inline-Funktionen werden vom Compiler erweitert, während die Makros vom Präprozessor erweitert werden, was eine reine Textsubstitution ist.

Somit,

  • Während des Makroaufrufs findet keine Typprüfung statt, während die Typprüfung während des Funktionsaufrufs erfolgt.

  • Unerwünschte Ergebnisse und Ineffizienz können während der Makroerweiterung aufgrund einer Neubewertung von Argumenten und einer Reihenfolge von Operationen auftreten. Zum Beispiel:

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

    würde dazu führen

    int i = 5, j = ((i++)>(0) ? (i++) : (0));
    
  • Die Makroargumente werden vor der Makroerweiterung nicht ausgewertet

     #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
    
  • Das Schlüsselwort return kann in Makros nicht verwendet werden, um Werte wie im Fall von Funktionen zurückzugeben.

  • Inline-Funktionen können überladen werden.

  • Die an Makros übergebenen Token können mit dem Operator verkettet werden ## namens Token-Einfügen Operator.

  • Makros werden im Allgemeinen für die Wiederverwendung von Code verwendet, wobei Inline-Funktionen verwendet werden, um den Zeitaufwand (überschüssige Zeit) während des Funktionsaufrufs zu eliminieren (um einen Sprung zu einer Unterroutine zu vermeiden).

Der Hauptunterschied ist die Typprüfung. Der Compiler prüft, ob das, was Sie als Eingabewerte übergeben, von Typen ist, die an die Funktion übergeben werden können. Das gilt nicht für Präprozessor-Makros – sie werden vor jeder Typprüfung erweitert und das kann schwerwiegende und schwer zu erkennende Fehler verursachen.

Hier sind einige andere weniger offensichtliche Punkte skizziert.

Um einen weiteren Unterschied zu den bereits gegebenen hinzuzufügen: Sie können nicht durch a gehen #define im Debugger, aber Sie können eine Inline-Funktion durchlaufen.

1646956819 126 Inline Funktionen vs Praprozessor Makros
Kirill V. Ljadwinski

Makros ignorieren Namespaces. Und das macht sie böse.

1646956821 441 Inline Funktionen vs Praprozessor Makros
Ahmad

Inline-Funktionen ähneln Makros (da der Funktionscode zum Zeitpunkt des Aufrufs zur Kompilierzeit erweitert wird), Inline-Funktionen werden vom Compiler analysiert, während Makros vom Präprozessor erweitert werden. Daher gibt es einige wichtige Unterschiede:

  • Inline-Funktionen befolgen alle Protokolle der Typsicherheit, die für normale Funktionen erzwungen werden.
  • Inline-Funktionen werden mit der gleichen Syntax wie jede andere Funktion angegeben, außer dass sie das Inline-Schlüsselwort in der Funktionsdeklaration enthalten.
  • Ausdrücke, die als Argumente an Inline-Funktionen übergeben werden, werden einmal ausgewertet.
  • In einigen Fällen können Ausdrücke, die als Argumente an Makros übergeben werden, mehr als einmal ausgewertet werden.
    http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx

  • Makros werden vor der Kompilierung erweitert, Sie können sie nicht zum Debuggen verwenden, aber Sie können Inline-Funktionen verwenden.

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

;

989330cookie-checkInline-Funktionen vs. Präprozessor-Makros

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy