Verschachtelte Funktionen sind nicht erlaubt, aber warum verschachtelte Funktionsprototypen erlaubt sind? [C ++]

7

Ich habe die verknüpfte Frage gelesen, die mich dazu bringt, diese Frage zu stellen.

Betrachten Sie den folgenden Code

%Vor%

Alles sagt, dass der Compiler das als Funktionsprototyp verwendet und nicht als String -Objekt. Betrachten Sie nun den folgenden Code.

%Vor%

Der Compiler hat gesagt, dass dies ungültig ist, da ich vermute, dass die geschachtelte Funktionsdefinition nicht erlaubt ist. Wenn es nicht erlaubt ist, warum geschachtelte Funktionsprototypen erlaubt sind? Es gibt keinen Vorteil, anstatt Verwirrung zu stiften (oder fehlen mir hier einige gültige Punkte?).

Ich habe herausgefunden, dass das Folgende gültig ist.

%Vor%

Das ist auch verwirrend. Ich habe erwartet, dass die Funktion SomeFun () nur einen Bereich in main hat. Aber ich habe mich getäuscht. Warum Compiler ermöglicht, Code wie oben zu kompilieren? Gibt es Situationen in Echtzeit, in denen Code wie oben sinnvoll ist?

Irgendwelche Gedanken?

    
Navaneeth K N 30.05.2009, 04:25
quelle

6 Antworten

8

Ihr Prototyp ist nur ' Forward Declaration '. Bitte schau dir den Wikipedia-Artikel an.

Grundsätzlich sagt es dem Compiler "sei nicht alarmiert, wenn das Label 'SomeFun' auf diese Weise verwendet wird." Aber dein Linker ist verantwortlich dafür, den richtigen Funktionskörper zu finden.

Sie können einen gefälschten Prototyp, z. 'Char' SomeFun () 'und benutze es überall auf deinem Main. Sie erhalten nur einen Fehler, wenn Ihr Linker versucht, den Körper Ihrer falschen Funktion zu finden. Aber dein Compiler wird damit cool sein.

Es gibt viele Vorteile. Sie müssen sich daran erinnern, dass sich der Funktionskörper nicht immer in der gleichen Quellcodedatei befindet. Es kann in einer verbundenen Bibliothek sein. Außerdem kann diese verbundene Bibliothek eine spezifische 'Verbindungssignatur' haben. Bedingte Bedingungen definieren, können Sie sogar die korrekte Verbindungsunterschrift zur Erstellungszeit unter Verwendung Ihrer begrenzten Prototypen auswählen. Obwohl die meisten Leute Funktionszeiger für verwenden würden stattdessen.

Hoffe, das hilft.

    
kervin 30.05.2009, 04:42
quelle
7

Nur als Nebenbemerkung hat C ++ 03 eine umständliche Art lokale Funktionen zu definieren. Es erfordert den Missbrauch der Local-Class-Funktion:

%Vor%     
Iraimbilanja 30.05.2009 09:38
quelle
5

Dies ist eine Konvention von C - wie viele - die C ++ übernommen hat.

Die Fähigkeit, eine Funktion innerhalb einer anderen Funktion in C zu deklarieren, ist eine Entscheidung, die die meisten Programmierer wahrscheinlich als bedauerlich und unnötig betrachten. Insbesondere bei modernen OOP-Designs, bei denen Funktionsdefinitionen vergleichsweise kleiner sind als in C.

Wenn Sie Funktionen haben möchten, die nur im Rahmen einer anderen Funktion existieren, sind zwei Optionen boost :: lambda und C ++ 1x Lambda .

    
Drew Dormann 30.05.2009 04:35
quelle
5

Warum Ihre Erklärung von

%Vor%

ist besser als dieser

%Vor%

Es ist generell gut, wenn Sie Deklarationen so lokal wie möglich halten, damit möglichst wenig Namenskonflikte entstehen. Ich sage, es ist strittig, ob eine Funktion lokal (auf diese Weise) wirklich glücklich ist, da ich denke, dass es immer noch besser ist, seinen Header zu verwenden und dann den "üblichen" Weg zu gehen, der auch weniger verwirrend ist Leute, die das nicht wissen. Manchmal ist es auch nützlich, eine Schattenfunktion zu umgehen

%Vor%

Natürlich könnten wir in C ++ die Funktion g mit its_namespace::g() aufrufen - aber in den alten Tagen von C wäre das nicht möglich gewesen, und dieses Ding erlaubte dem Programmierer, immer noch auf die Funktion zuzugreifen. Beachten Sie auch, dass syntaktisch nicht dasselbe ist, aber das Folgende deklariert semantisch auch eine Funktion innerhalb eines lokalen Bereichs, die eigentlich auf einen anderen Bereich abzielt.

%Vor%

Als Nebenbemerkung gibt es mehrere Situationen, in denen der Zielbereich einer Deklaration nicht der Bereich ist, in dem diese Deklaration angezeigt wird. Im Allgemeinen wird die deklarierte Entität ein Mitglied der Deklaration Umfang, in dem die Deklaration erscheint. Aber das ist nicht immer der Fall. Betrachten Sie zum Beispiel Freundschaftsdeklarationen, wo das Ding passiert

%Vor%

Obwohl die Funktionsdeklaration (und Definition!) von f innerhalb des Bereichs von X stattfand, wurde die Entity (die Funktion selbst) ein Member des umschließenden Namespace.

    
Johannes Schaub - litb 30.05.2009 15:12
quelle
3

Funktionsprototypen sind Hinweise für den Compiler. Sie zeigen an, dass die Funktionen woanders implementiert sind, wenn sie nicht bereits entdeckt sind. Nichts mehr.

    
Nick Dandoulakis 30.05.2009 04:42
quelle
3

Wenn Sie einen Prototyp deklarieren, teilen Sie dem Compiler im Grunde mit, dass er auf den Linker warten soll, um ihn zu lösen. Je nachdem, wo Sie den Prototyp schreiben, gelten die Scoping-Regeln. Es gibt nichts technisch falsch Schreiben des Prototyps innerhalb Ihrer Main () -Funktion (obwohl IMHO ein bisschen unordentlicher), es bedeutet nur, dass die Funktion nur lokal innerhalb der Main () bekannt ist. Wenn Sie den Prototyp am Anfang Ihrer Quelldatei (oder häufiger in einer Header-Datei) deklariert hätten, wäre der Prototyp / die Funktion in der gesamten Quelle bekannt.

%Vor%     
Anders K. 30.05.2009 08:07
quelle