2012-06-12 13 views
13

Ich arbeite in der C-Sprache und modifiziere Code zuvor von jemand anderem geschrieben. Ich kämpfe mit ein paar Dingen und versuche so viel wie möglich über das, was vor sich geht, zu verstehen. Also, wie meine Frage sagte, was ist der Unterschied zwischen und void beim Erstellen einer Funktion? Ich entschuldige mich im Voraus für den langen Post, aber ich wollte, dass Sie wissen, dass ich etwas recherchiert habe, aber nicht verstehe, was ich gefunden habe.Was ist der Unterschied zwischen statischem inline void und void?

Ich fand an explanation of static das verwirrt mich:

Der statische Bezeichner bedeutet, dass die Funktion nicht aus anderen Dateien referenziert werden; Das heißt, der Name wird nicht vom Linker exportiert.

Wenn ich das lese, nehme ich an, dass die Referenzierung einer Funktion anders ist als das Aufrufen einer Funktion? Ich gehe davon aus, dass diese Funktion aus einer anderen .c-Datei aufgerufen wird. Wenn dies der Fall ist, was bezieht sich auf eine Funktion?

Durch die gleiche Website erklären sie inline functions und ich verstehe nicht, was es bedeutet.

Das __inline Schlüsselwort teilt dem Compiler den Code innerhalb die Funktionsdefinition für jede Instanz eines Funktionsaufrufs zu ersetzen. Die Ersetzung erfolgt jedoch nur im Ermessen des Compilers. Für Beispiel führt der Compiler eine Funktion nicht inline ein, wenn seine Adresse ist, oder wenn es für Inline zu groß ist.

Huh ???

Jede Hilfe wird sehr geschätzt, und ich entschuldige mich noch einmal für die schrecklich lange Post.

Das Folgende ist in file1.c befindet (generische Namen verwenden, wie ich glaube nicht, dass es darauf ankommt)

COMPLEX cNoiseSample; 
CGauss(&cNoiseSample, loopbackRadio->pState); 

Die folgende

in file2.c befindet
static inline void CGauss(COMPLEX * pcGauss, P_OS_UNIFORM_RAND_STATE pState) 
{ 
    //code 
} 

Antwort

12

static bedeutet, dass es nicht von einer anderen Kompilierungseinheit (Quelldatei) referenziert werden kann. "Referenziert" bedeutet genannt oder anderweitig mit Namen bezeichnet, z. einem Funktionszeiger zugewiesen.

inline ist ein Hinweis für den Compiler, dass der Code der Funktion inline an der Stelle generiert werden sollte, an der er aufgerufen wird, anstatt als separate Funktion zum Verzweigen generiert zu werden. Dies geschieht normalerweise aus Leistungsgründen. Um mit Microsoft Zitat:

die Compiler keine Inline eine Funktion, wenn ihre Adresse übernommen wird, oder wenn es zu groß, um inline.

Eine Inlinefunktion hat keine Adresse, da sie nicht als separate Entität existiert. Sein Code ist nahtlos mit dem Code, von dem er aufgerufen wird, verflochten. Wenn Sie also die Adresse einer Funktion verwenden (z. B. einem Zeiger zuweisen), muss der Compiler sie als echte Funktion generieren und nicht inline.

void bedeutet, dass die Funktion keinen Wert zurückgibt.


an Ihrem Codebeispiel sah Nachdem ich würde vermuten, dass es eine gesonderte Definition von CGauss() irgendwo ist, die von file1.c ist, während file2.c genannt wird über einen eigenen Aufruf Ausführung. Entweder das oder file1.c ist #include ing file2.c. Was wäre böse.

+0

auch, 'inline' ist notwendig, um die Ein-Definition-Regel zu erzwingen, wenn eine Funktion in einem Header in verschiedenen Kompilierungseinheiten definiert ist (oder zumindest das ist der Fall für C++, kenne dieses Detail nicht genau in C, I stell dir vor, es wird gleich sein) – rubenvb

+0

Nun ich denke, ich bin ein wenig verwirrt als @ Graham-Borland. Lassen Sie mich Ihnen zeigen warum: COMPLEX cNoiseSample; CGauss (& cNoiseSample, loopbackRadio-> pState);/* Dieser Code wird an einer Stelle in einer .c-Quelldatei aufgerufen, und in einer anderen .c-Quelldatei habe ich folgendes: */static inline void CGauss (KOMPLEX * pcGauss, P_OS_UNIFORM_RAND_STATE pState)/* Ich entschuldige mich für die schlechte Formatierung Im Kommentarfeld war ich nicht sicher, wie ich das sonst tun sollte. */ – TZPike05

+0

Bearbeiten Sie Ihre Frage, fügen Sie das Code-Snippet dort ein. –

6

static bedeutet nur etwas, wenn Sie mehr als eine Quelldatei haben. Es gibt an, dass auf die Funktion oder Variable static nicht von Funktionen in einer anderen Datei zugegriffen werden kann.

inline ist eine Compiler-Optimierung, die in bestimmten Fällen Ihren Code beschleunigt. Jedes Mal, wenn Sie eine Funktion aufrufen, ist ein gewisser Overhead damit verbunden. Also, was der Compiler tun kann, ist die Funktion all-together durch Kopieren + Einfügen (fast) der Inline-Code loszuwerden.

Hier ist ein Beispiel von inlining:

int dotproduct(int x1, int y1, int x2, int y2) { 
    return multiply(x1,x2)+multiply(y1,y2); 
} 

inline int multiply(int a, int b) { 
    return a*b; 
} 

Der Compiler dies in drehen wird:

int dotproduct(int x1, int y1, int x2, int y2) { 
    return x1*x2+y1*y2; 
} 

Wenn Sie Lust sein wollen, können Sie auch die dotproduct Funktion inline;)

Beachten Sie, dass das Schlüsselwort inline lediglich ein Anstoß an den Compiler ist, bestimmte Funktionen zu verknüpfen. Es kann oder kann es nicht wirklich tun, abhängig von seinem eigenen Urteil.

+0

Dank @tskuzzy, Inline macht jetzt viel mehr Sinn. – TZPike05

0

statische bedeutet nur, dass im wesentlichen die Funktion für alle Absichten und Zwecke ‚unsichtbar‘ außerhalb der Quelldatei, die es in definiert ist.

inline die Compiler askes den Funktionsaufrufcode direkt in die Quelle im wesentlichen substite an jedem Ort wird die Funktion zur Kompilierzeit aufgerufen (wie eine Ersetzung des Funktionsaufrufs durch den Code der Funktion) - es ist jedoch nicht garantiert, dass sie auftritt, sondern nur Ihrem Compiler.

Es ist technischer als das und Sie werden wahrscheinlich eine viel bessere Antwort bekommen, aber in einfacher Sprache das ist, was die Begriffe bedeuten.

2

Der statische Schlüsselwort

eine C-Funktion statische definierende Einrichtung (wie die Dokumentation sagen), dass diese Funktion nur von der Quelle Datei zugegriffen werden kann, es in definiert. Den Begriff ‚Referenz‘ in diesem Sinne Mitteln Entweder ruft man diese Funktion auf oder nimmt zum Beispiel einen Funktionszeiger darauf.

Inlining

Normalerweise, wenn Sie eine Funktion in C schreiben, erzeugt der Compiler den Maschinencode für diese Funktion:

foo: 
    /* some machine code */ 
    ret 

Jedes Mal, wenn Sie diese Funktion aufrufen, der Compiler eine Anweisung einfügt wie

call <foo> 

in den Maschinencode des Anrufers, was nichts anderes bedeutet als "zu foo springen, e Was passiert dort? Wenn du auf eine Anweisung für ret kommst, kehre an diesen Ort zurück. "

Im Gegensatz dazu erzeugt der Compiler für Inline-Funktionen keine separate Funktion foo(), sondern fügt den Maschinencode für die Funktion foo in jede Aufrufstelle ein. Wenn Sie diesen Code ausführen, hat dies den gleichen Effekt.

Also warum machen wir das? Inlining-Code hat den Vorteil, dass Sie zwei Sprünge (den Call und das entsprechende ret) speichern, wodurch Ihr Code etwas schneller ausgeführt wird. Als Nachteil wird Ihr Code größer, weil Sie den Maschinencode an jeder Aufrufseite einfügen, anstatt nur eine Kopie einer aufrufbaren Funktion zu haben. Deshalb gibt es normalerweise nur kleine Inline-Funktionen.

Außerdem können Funktionszeiger nicht auf Inline-Funktionen angewendet werden, und das Debugging wird schwieriger, da Sie einen Breakpoint für eine Inline-Funktion nicht einfach festlegen können.

Daher inlining ist für den Compiler als Optimierungsoption links und durch ein Schlüsselwort wie C++ 's inline, Ihr Inline-Direktive oder GCC __attribute ((inline)) verwenden, können Sie nur dem Compiler einen Hinweis darauf geben, dass inlining könnte einen Versuch hier wert sein.

Verwandte Themen