Schreibe ein kurzes Programm, das die längste mögliche Fehlermeldung erzeugen würde, in einem Standard - C ++ Kompilierer ( gcc
, cl.exe
, icc
, oder clang
).
Die Punktzahl jedes Eintrags ist die Anzahl der Zeichen in der längsten Fehlermeldung, die der Compiler ausgegeben hat. Typen, die in Ihrem Quellcode enthalten sind und vom Compiler in Anführungszeichen gesetzt werden, werden als ein einzelnes Zeichen gezählt.
Betrug
Sie können eine Vorlage in einer Vorlage mit langen Namen immer neu definieren, aber ich erwarte etwas Kreatives. Ich habe versucht, dies durch die letzte Regel zu verhindern, aber natürlich können die Regeln besser sein, und ich freue mich über Verbesserungen.
code-challenge
c++
error-message
Elazar Leibovich
quelle
quelle
Error.message.length / code.length
.Antworten:
Vorlagen-Fehlermeldungen machen Spaß, sie zu entziffern. Bedenken Sie:
Das Kompilieren mit
gcc -c error.cpp
(4.6.3) ergibt 15786 Bytes Ausgabe mit einer längsten Zeile von 330 Zeichen.Edit 2016-04-29: gcc 5.3.0 hat es ein bisschen besser: nur 9300 Bytes, die längste Zeile ist 361 Zeichen lang ...
Edit 2019-04-04: gcc 6.5.0: 11237 bytes, gibt aber einige Hinweise zum Fehler, wie in diesen Zeilen:
quelle
19 Zeichen
Erstellen Sie eine Datei
a.cpp
mit diesem Inhalt:Kompilieren als:
und bekomme erstaunliche 21300 Zeilen Fehlermeldungen :
...
... 21280 Fehlerzeilen ...
...
quelle
#include __FILE__
und einem sehr langen Dateinamen ..?clang++ -ferrorlimit=1000 a.cpp
. Die längste Zeile ist 466 Zeichen lang.98 (notwendige) Zeichen:
Erzeugt die folgende Fehlerausgabe in GCC (4.4.5):
Statistiken:
Ungolfed (erzeugt längere Ausgabe):
Ich entdeckte dies, als ich herausfinden wollte, ob C ++ die polymorphe Rekursion unterstützt (und wie Sie sehen können, nicht). Hier ist ein triviales Beispiel für eine polymorphe Rekursion in Haskell:
Hier erfordert dies Haskell zu handeln , wie es instanziiert
Show x
,Show [x]
,Show [[x]]
,Show [[[x]]]
, ad infinitum. Haskell verwandelt sich dazu(Show x) =>
in einen impliziten Parameter für dief
vom Compiler hinzugefügte Funktion.C ++ versucht buchstäblich, solche Instanzen zu erstellen, bis die Tiefe der Template-Instanziierung überschritten ist.
quelle
cl
mag keine implizitint
in C ++ Modus) erzeugt es 14.380.923 Bytes der Fehlerausgabe nach 4½ Minuten von CPU - Zeit und einem Spitzenwert von etwa 100 MiB der Speichernutzung.Basierend auf einem Verhältnis von Nachrichtenlänge zu Codelänge ist dies möglicherweise die beste Lösung:
Nachricht (81):
81/0 = Inf
quelle
279 Zeichen
Mit gcc 4.2.1 wird der Fehler
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘foofoo....foofoo’
mit 2 ^ 21 Kopien von erzeugtfoo
. Insgesamt 6.291.558 Byte. Es ist etwa so groß wie eine Kennung ich bekommen kann, zu ersetzenfoo
mitfood
einem ICE erzeugt.quelle
#define A(s) s##s##s##s #define B(s) A(s) #define C(s) B(B(B(s))) #define D(s) C(C(C(s))) D(foo)
. Dadurch erhalte ich eine ungefähr so lange Fehlermeldung mit weniger Code und wächst mit zunehmendem Muster in jeder Dimension viel schneller, da wir im Wesentlichen die Ackermann-Funktion implementieren.Ähnlich wie VJo:
a.cpp:
g ++ a.cpp
produziert viel Output (mindestens 2 Gigabyte bevor ich es getötet habe)
quelle
Der folgende Code basiert auf einem tatsächlichen Fehler, auf den ich einmal gestoßen bin.
(mit gcc)
Ziemlich offensichtliche Template-Rekursion, aber da ich
ftemplate-depth=100000
für diesen Lauf verwendet habe, wird kein Fehler erzeugt. Die eigentliche Quelle der Fehlermeldungen stammt vonchar baz[i];
, die bei einem Fehler erzeugt werdeni
auf -1 abfallen.Nach ungefähr einer halben Stunde kann ich 21.000 Compilerfehler , 300.000 Zeilen Fehlermeldungen und 280 Megabyte RAM feststellen, die vom Compiler verwendet werden. Und es zeigt keine Anzeichen eines Anhaltens.
BEARBEITEN:
Eine Stunde später, jetzt bei 36.000 Compilerfehlern , 504.000 Zeilen Fehlermeldungen und 480 Megabyte RAM ... und immer noch in Betrieb.
EDIT # 2:
Etwa eine halbe Stunde später:
Endgültige Statistik: 38.876 Compilerfehler , 544.624 Zeilen Fehlermeldungen, insgesamt 48,8 Megabyte Daten und 518,9 Megabyte RAM, die vom Compiler vor dem Absturz verwendet wurden.
quelle
28 Bytes
Sabotage der Standardbibliothek:
Verwenden von clang unter OS X 10.9:
456 Fehlerzeilen , 50 Fehler und ein Compiler-Segfault !
Clang-Version:
quelle
Ich bin zufällig darauf gestoßen:
Unter c ++ x11 werden 44 KB Fehlermeldungen ausgegeben, in denen der Compiler versucht zu sagen: Definieren Sie den Platzhalter für das erste Argument, wenn Sie ihn für das zweite definieren.
Sieh es auf ideone .
quelle
C ++
Basierend auf BЈовићs Lösung:
Datei: golf.cpp:
Das Ausführen unter G ++ wird nicht beendet, ich habe jedoch die Länge des Fehlers berechnet, der schließlich als ungefähr 85 * 2 ^ 140 Terabyte ausgegeben wird.
quelle
C ++ 11-Vorlagen (69 Zeichen)
Durch Konfigurieren der maximalen Tiefe der Vorlageninstanzierung können Sie die Länge des Fehlers festlegen. Hier ist ein Beispiel für die Verwendung von GCC 4.8.1 mit der Standardvorlagentiefe (900):
Sie können auch zehn weitere Zeichen hinzufügen und einen vorzeichenlosen Ganzzahlunterlauf verwenden, um die Länge des Fehlers zu erhöhen:
Hier ist ein Beispiel, das bei ideone läuft.
quelle
82 Bytes: Dieser funktioniert ähnlich wie der Ansatz von Joey Adams , aber die Fehlermeldung wächst exponentiell in Bezug auf
-ftemplate-depth
(weilstd::set<T>
es tatsächlich so iststd::set<T, std::less<T>, std::allocator<T>>
).Für
(x = -ftemplate-depth) >= 28
wird es 1460 × 3 x-27 + 269x - 5381 Bytes an Fehlermeldungen geben (kompiliert von gcc 7.2.0). Das heißt, in den Standardeinstellungen (x = 900) werden theoretisch etwa 4,9 × 10 419 Byte Fehlermeldung ausgegeben .Beachten Sie, dass
return
die Fehlermeldungen ohne die Anweisung erst am Ende der Kompilierung ausgegeben werden. (In den Standardeinstellungen werden die Nachrichten nicht angezeigt. Der Arbeitsspeicher wird zuerst ausgehen.)Warnung: Das Kompilieren dieses Programms belegt viel Speicher.
Probieren Sie es online!
quelle
map
scheint streng mehr böse, dastd::map<T,T>
iststd::map<T,T,std::less<T>,std::allocator<std::pair<T,T>>>
man Rekursion 5-Wege so erhalten anstelle von 3, für nur 2 weitere Bytes.-ftemplate-depth=13
, 423.572 Bytes bei-ftemplate-depth=14
und 1.247.322 Bytes bei-ftemplate-depth=15
.map
Variante generiert 13.373.990 Bytes in Tiefe 14 und 66.759.871 Bytes in Tiefe 15.-ftemplate-depth=1024
, dh irgendwo nördlich von 10 ^ 713 Bytes mit dermap
Variante. Ich glaube, das heißt, Sie gewinnen ...Dies erzeugt eine unendliche Ausgabe unter GCC 5.2 und Clang 3.6 (unter Clang erforderlich
-ferror-limit=0
, unter GCC wird mit Standardeinstellungen gearbeitet):quelle
Eine Datei mit dem Namen
a.cpp
. Code:Dies ist eine Gabelbombe mit n = 40.
quelle
=>
=>
kompilieren mit
index_sequence scheint das Problem mit der Schabloneninstanziierungstiefenbeschränkung zu umgehen
Fehler sehen so aus: Die gesamte 0 ... C-1-Zahlenfolge sieht aus, als würde sie 4 * C-mal gedruckt
und die Zahlensequenzen können die Standardgrenze für die Vorlageninstanziierung überschreiten, sicherlich, weil sie eingebaut sind:
quelle