C ++ - Vorlagen sind dafür berüchtigt, lange, unlesbare Fehlermeldungen zu generieren. Ich habe eine allgemeine Vorstellung davon, warum Vorlagenfehlermeldungen in C ++ so schlecht sind. Das Problem besteht im Wesentlichen darin, dass der Fehler erst ausgelöst wird, wenn der Compiler auf eine Syntax stößt, die von einem bestimmten Typ in einer Vorlage nicht unterstützt wird. Beispielsweise:
template <class T>
void dosomething(T& x) { x += 5; }
Wenn T
der +=
Operator nicht unterstützt wird, generiert der Compiler eine Fehlermeldung. Und wenn dies irgendwo tief in einer Bibliothek passiert, kann die Fehlermeldung Tausende von Zeilen lang sein.
C ++ - Templates sind jedoch im Wesentlichen nur ein Mechanismus für die Eingabe von Daten während der Kompilierung. Ein C ++ - Vorlagenfehler ist konzeptionell einem Laufzeitfehler sehr ähnlich, der in einer dynamischen Sprache wie Python auftreten kann. Betrachten Sie beispielsweise den folgenden Python-Code:
def dosomething(x):
x.foo()
Wenn x
hier keine foo()
Methode vorhanden ist, löst der Python-Interpreter eine Ausnahme aus und zeigt eine Stapelverfolgung zusammen mit einer ziemlich klaren Fehlermeldung an, die auf das Problem hinweist. Auch wenn der Fehler erst ausgelöst wird, wenn sich der Interpreter tief in einer Bibliotheksfunktion befindet, ist die Laufzeitfehlermeldung bei weitem nicht so schlimm wie das unlesbare Erbrochene, das von einem typischen C ++ - Compiler ausgegeben wird. Warum kann ein C ++ - Compiler nicht klarer sagen, was schief gelaufen ist? Warum führen einige Fehlermeldungen in C ++ - Vorlagen dazu, dass mein Konsolenfenster länger als 5 Sekunden gescrollt wird?
quelle
clang++
wink wink).Antworten:
Vorlagenfehlermeldungen sind notorisch, aber keineswegs immer lang und unlesbar. In diesem Fall lautet die gesamte Fehlermeldung (von gcc):
Wie in Ihrem Python-Beispiel erhalten Sie eine "Stapelverfolgung" von Vorlageninstanziierungspunkten und eine eindeutige Fehlermeldung, die auf das Problem hinweist.
Manchmal können vorlagenbezogene Fehlermeldungen aus verschiedenen Gründen viel länger werden:
Der Hauptunterschied zu Python ist das statische Typsystem, was dazu führt, dass die (manchmal langen) Typnamen in die Fehlermeldung aufgenommen werden müssen. Ohne sie wäre es manchmal sehr schwierig zu diagnostizieren, warum die Überlastungslösung fehlgeschlagen ist. Mit ihnen besteht Ihre Herausforderung nicht mehr darin, zu erraten, wo das Problem liegt, sondern die Hieroglyphen zu entziffern, aus denen hervorgeht, wo es sich befindet.
Die Überprüfung zur Laufzeit bedeutet auch, dass das Programm beim ersten aufgetretenen Fehler stoppt und nur eine einzige Meldung anzeigt. Ein Compiler zeigt möglicherweise alle aufgetretenen Fehler an, bis er aufgibt. Zumindest in C ++ sollte es nicht beim ersten Fehler in der Datei anhalten, da dies eine Folge eines späteren Fehlers sein kann.
quelle
Einige der offensichtlichen Gründe sind:
Das ist alles andere als erschöpfend, aber Sie haben eine allgemeine Vorstellung. Auch wenn es nicht einfach ist, kann das meiste davon geheilt werden. Seit Jahren fordere ich die Leute auf, eine Kopie von Comeau C ++ zur regelmäßigen Verwendung zu erhalten. Ich habe wahrscheinlich genug von einer Fehlermeldung einmal gespeichert, um für den Compiler zu bezahlen. Jetzt kommt Clang zum selben Punkt (und es ist noch billiger).
Ich werde mit einer allgemeinen Bemerkung schließen, die sich wie ein Witz anhört, aber wirklich nicht so ist. Die meiste Zeit, ein richtiger Job des Compilers ehrlich ist Quellcode in Fehlermeldungen zu drehen. Es ist höchste Zeit, dass sich die Anbieter darauf konzentrieren, diesen Job ein bisschen besser zu machen - obwohl ich offen zugeben werde, dass ich beim Schreiben von Compilern eine starke Tendenz hatte, ihn als zweitrangig zu behandeln (bestenfalls) und ihn in einigen Fällen fast ignorierte vollständig.
quelle
Die einfache Antwort ist, dass Python so entworfen wurde, dass es so funktioniert, während viele Dinge, die mit Vorlagen verbunden sind, zufällig entstanden sind. Es war zum Beispiel nie beabsichtigt, ein Turing-vollständiges System für sich zu werden. Und wenn Sie nicht absichtlich planen und überlegen können, was passiert, wenn Ihr System funktioniert , warum sollte dann jemand mit einer sorgfältigen und durchdachten Planung rechnen, was passiert, wenn etwas schief geht?
Wie Sie bereits betont haben, kann der Python-Interpreter die Anzeige eines Stack-Trace erheblich vereinfachen, da er Python-Code interpretiert. Wenn ein C ++ - Compiler auf einen Template-Fehler stößt und Ihnen einen Stack-Trace liefert, wäre das genauso wenig hilfreich wie "Template-Erbrochenes", nicht wahr?
quelle