Was ist der Unterschied in der Praxis zwischen inline-und #define?
Wie der Titel sagt; was ist der Unterschied in der Praxis zwischen den inline-Schlüsselwort und die #define-Präprozessor-Direktive?
- mögliche Duplikate von Inline-Funktionen von vs-Präprozessor-Makros
Du musst angemeldet sein, um einen Kommentar abzugeben.
#define
ist ein preprocessor-tool und hat makro-Semantik. Betrachten Sie diese, wennmax(a,b)
ist ein makro definiert als#define max(a,b) ((a)>(b)?(a):(b))
:Ex 1:
val = max(100, GetBloodSample(BS_LDL))
würde spill extra unschuldiges Blut, denn die Funktion wird tatsächlich zweimal aufgerufen werden. Dies könnte bedeuten, erhebliche performance-Unterschied für echte Anwendungen.Ex 2:
val = max(3, schroedingerCat.GetNumPaws())
Dies zeigt eine gravierenden Unterschied in der Programm-Logik, denn dieser kann unerwartet eine Zahl zurückgeben, die weniger als 3 - etwas, das der Benutzer nicht erwarten würde.
Ex 3:
val = max(x, y++)
könnte Inkrementy
mehr als einmal.Mit inline-Funktionen, keine der beiden wird passieren.
Der Hauptgrund ist, dass der makro-Konzept-Ziele-Transparenz der Umsetzung (Text-code ersetzen) und inline-Ziele ordnungsgemäße Sprache, Konzepte, so dass die Aufruf-Semantik mehr für den Benutzer transparent.
shroedingerCat.GetNumPaws()
eine C-Funktion, nicht C++.Funktionen (ob
inline
oder nicht) und Makros erfüllen unterschiedliche Zwecke. Der Unterschied, das sollte man nicht als ideologische, wie einige scheinen, es zu nehmen, und, was noch wichtiger ist, Sie arbeiten gut zusammen.Makros sind text-replacement, erfolgt zur compile-Zeit, und Sie können Dinge tun, wie
die Ihnen eine compile-Zeit-Ausdruck, ob oder ob nicht ein integraler Typ ist, unterzeichnet oder nicht. Das heißt, Sie sind ideal eingesetzt, wenn der Typ eines Ausdrucks nicht bekannt ist (bei der definition) und Sie wollen etwas dagegen tun. Auf der anderen Seite, das Problem mit Makros ist, dass Ihre Argumente evaluiert werden kann mehrere Male, das ist schlecht wegen der Nebenwirkungen.
Funktionen (
inline
) auf der anderen eingegeben werden, das macht Sie strenger, oder, negativ formuliert, weniger flexibel. Betrachten Sie die FunktionenDen ersten implementiert das trivial
abs
Funktion für eine vorzeichenlose Integrale Typ. Die zweite setzt es für einen signed-Typ. (ja, es dauert eine vorzeichenlose als argument, ist dies für den Zweck.)Wir können diese mit beliebigen ganzzahligen Typ. Aber der Rückgabetyp wird immer von der größten Breite und es gibt eine gewisse Schwierigkeit, zu wissen, wie Sie wählen Sie zwischen den beiden.
Nun mit dem folgenden makro
haben wir umgesetzt
der compiler wird bei der Schaffung von optimalen code
(Gut, ich gebe zu, dass dies mit
abs
ist ein bisschen künstlich, aber ich hoffe, Sie bekommen das Bild.)Makros (erstellt mit
#define
) werden immer ersetzt, wie geschrieben, und kann doppelt Auswertung Probleme.inline
auf der anderen Seite, ist eine rein beratende - der compiler ist frei, es zu ignorieren. Unter dem C99-standard, eininline
- Funktion können auch externe Verknüpfung, erzeugen die definition einer Funktion verknüpft werden können gegen.Gut, eine multi-line -
#define
ist schwieriger zu schreiben und zu Bearbeiten, als eine inline-Funktion. Sie können die Definition einer inline-Funktion genauso wie eine normale Funktion, und definieren können Variablen ohne Probleme. Angenommen, Sie möchten rufen Sie einen code-block mehrere Male innerhalb einer anderen Funktion, und dieser code-block muss seine eigenen Variablen: es ist einfacher, mit inline-Funktionen (ja, Sie können dies tun, mit #defines unddo { ... } while (0);
aber es ist etwas, was Sie zu denken haben).Auch, mit aktivierten debugging, normalerweise bekommt man eine "simulierte" stack-frame für inline-Funktionen, die machen könnte einfacher Debuggen, manchmal (zumindest das ist, was Sie bekommen, wenn Sie die Compiler - /link-mit gcc
-g
und Debuggen mit GDB, wenn ich mich Recht erinnere). Sie können Haltepunkte in Ihre inline-würde-Funktion.Abgesehen davon sollte das Ergebnis fast identisch, AFAIK.
Den Unterschied beschrieben wird, ziemlich in die Tiefe, hier :
http://www.geekinterview.com/question_details/23831
cheers
Function-like Makros geben Ihnen absolut null sanity checks an der Stelle, wo Sie definiert sind. Wenn Sie die Schraube mit einem makro, es wird funktionieren gut in einem Ort gebrochen, irgendwo anders, und man weiß nicht, warum, bis Sie verloren haben, mehrere Stunden Arbeit/Zeit schlafen. Function-like Makros funktionieren nicht auf Daten, die Sie betreiben, auf dem source-code. Manchmal ist dies gut, zum Beispiel, wenn Sie wollen, wieder verwendbare debug-Anweisungen verwenden DATEI und LINIE gelieferten, aber die meisten der Zeit, es kann getan werden, ebenso gut mit einer inline-Funktion, die überprüft, die syntax an der Stelle der definition genau wie jede andere Funktion.