Rückgabetypableitung mit einem expliziten Prototyp in C ++

8

Ich habe mit dem Rückgabetyp-Abzug gespielt, der in g ++ mit -std = c ++ 1y unterstützt wird.
Wenn Sie eine Funktion mit einem expliziten Rückgabetyp prototypieren und später versuchen, die Funktion mit der Rückgabetypableitung zu definieren, beschwert sich der Compiler über eine mehrdeutige alte Deklaration:

%Vor%

Gibt es einen guten Grund, warum das nicht funktioniert?
Mein Grundprinzip für die Verwendung der Rückgabetypableitung in der Definition ist, den Code sauber zu halten, aber einen expliziten Typ des Prototyps für selbstdokumentierende Gründe. Empfehlungen zu Best Practices für den Fall, wann und wann der Abzug vom Rückgabetyp nicht verwendet werden sollte, wären wünschenswert:)

Um klarer zu sein, möchte ich Antworten auf:
1. Ist das ein Implementierungsfehler im Compiler? (Ich bin ziemlich sicher, dass es nicht ist)
2. Könnte diese Art von Abzug vorgenommen werden, ist aber durch den Vorschlag zum Standard nicht erlaubt? Wenn ja, warum nicht?
3. Wenn das wirklich mehrdeutig ist, was sind Beispiele dafür, wenn Sie den Typ ableiten und versuchen, ihn mit einer expliziten Forward-Deklaration abzugleichen? 4. Gibt es tiefere umsetzungsspezifische Probleme dahinter?
5. Ist es einfach ein Versehen?

    
mio iwakura 29.08.2013, 19:36
quelle

2 Antworten

6

Das liegt daran, wie die Funktionstabellen und überladenen Funktionen in C ++ funktionieren.

Wenn der Compiler Ihren std::string some_function(); liest, erzeugt er einen Punkt, auf den er in der Binärdatei verweisen kann, und sagt, wenn "diese Funktion jemals an dieser Stelle aufgerufen wird".

Also haben wir eine vtable, die so aussieht ...

%Vor%

Jetzt geht es zu deinem auto some_function() {...} . Normalerweise würde es zuerst in der Funktionstabelle nachsehen, ob auto somefunction(); in der Tabelle vorhanden ist oder eine Variation davon, aber der Compiler merkt, dass dies eine Implementierung ist und das Schlüsselwort auto hat, um die Entropie zu reduzieren, schreibt es *blank* some_function(); an die Funktionstabelle und Bindungen, um den Rückgabetyp zu lösen.

Nun sieht die Funktionstabelle so aus ...

%Vor%

Also tuckert es den Code in Binärcode kompilieren, wenn er den Rückgabetyp findet, der in diesem Fall std::string ist. Der Compiler weiß jetzt, was der Rückgabetyp ist, also geht er zur Funktionstabelle und ändert auto somefunction(); too std::string somefunction(); .

Nun sieht die Funktionstabelle so aus ...

%Vor%

Nun geht der Compiler zurück und kompiliert die Funktion weiter. Sobald es fertig ist, geht es zurück und beendet die vtable, nur um zu finden, dass das gleiche Symbol zweimal drin ist. Es ist jetzt mehrdeutig, auf welches Symbol wir uns beziehen.

Was ist der Grund dafür?

Nicht zu 100% sicher, aber vtables werden erstellt, lange bevor der Code ausreichend bearbeitet wurde, um den Abzugstyp zu ermöglichen. Die einzige Option, mit der der Compiler zu diesem Zeitpunkt arbeiten muss, ist, einfach davon auszugehen, dass es ein neues Symbol ist. Es ist nur etwas, das mir aufgefallen ist, dass ich den ganzen Tag auf Symboltabellen gestanden bin und meinen eigenen C ++ 11-Compiler geschrieben habe.

Ich kann jedoch in keiner Weise für andere Compiler sprechen, bei denen viele Optimierungen und andere Schritte eingeführt werden, ich arbeite nur mit den nackten Knochen, aber das ist mein Verständnis des Standards.

Eine letzte Sache ist der Typ völlig willkürlich. Es spielt keine Rolle, ob sie zum Zeitpunkt des Abzugs nicht übereinstimmen. Es wird nie so weit kommen. Das Problem besteht darin, dass zwei gleiche Symbole in der Tabelle vorhanden sind und Sie die Rückgabetypen nicht überladen können.

    
Matt Kaes 03.09.2013, 16:38
quelle
-3

Sie müssen es tun als:

%Vor%

Weitere Informationen finden Sie in Ссылка - & gt; alternative Funktionssyntax

    
Michał Walenciak 29.08.2013 19:43
quelle