Ecrire un programme court, qui générerait le plus long message d'erreur possible, dans une norme C ++ compilateur ( gcc
, cl.exe
, icc
ou clang
).
Le score de chaque entrée est le nombre de caractères du message d'erreur le plus long émis par le compilateur. Les types inclus dans votre code source et cités par le compilateur sont comptés comme un seul caractère.
La triche
Vous pouvez toujours redéfinir un modèle dans un modèle avec des noms longs, mais je m'attends à quelque chose de créatif. J'ai essayé d'empêcher une partie de cela par la dernière règle, mais bien sûr, les règles peuvent être meilleures, et je serai ravi d'apporter des améliorations.
code-challenge
c++
error-message
Elazar Leibovich
la source
la source
Error.message.length / code.length
.Réponses:
Les messages d'erreur de modèle sont amusants à déchiffrer. Considère ceci:
Compiler avec
gcc -c error.cpp
(4.6.3) produira 15 086 octets de sortie, avec une plus longue ligne de 330 caractères.Edit 2016-04-29: gcc 5.3.0 l'a un peu mieux: seulement 9300 octets, la plus longue ligne fait 361 caractères ...
Edit 2019-04-04: gcc 6.5.0: 11237 octets, mais donne quelques indications sur l'erreur, comme dans ces lignes:
la source
19 personnages
Créez un fichier
a.cpp
avec ce contenu:Compiler en tant que:
et obtenez d’étonnants messages d’ erreur de 21 300 lignes :
...
... 21280 lignes d'erreur ...
...
la source
#include __FILE__
et un nom de fichier très long ..?clang++ -ferrorlimit=1000 a.cpp
. La ligne la plus longue comporte 466 caractères.98 caractères (nécessaires):
Génère la sortie d'erreur suivante dans GCC (4.4.5):
Statistiques:
Ungolfed (produit une sortie plus longue):
J'ai découvert cela lorsque je voulais voir si C ++ prenait en charge la récursion polymorphe (et, comme vous pouvez le constater, cela ne le fait pas). Voici un exemple trivial de récursion polymorphe dans Haskell:
Ici, cela nécessite Haskell d'agir comme il instancie
Show x
,Show [x]
,Show [[x]]
,Show [[[x]]]
, ad infinitum. Haskell le fait en se transformant(Show x) =>
en un paramètre implicite de la fonctionf
ajoutée par le compilateur, quelque chose comme ceci:C ++ le fait en essayant littéralement de construire de telles instances jusqu'à ce que la profondeur d'instanciation du modèle soit dépassée.
la source
cl
n’est pas impliciteint
en mode C ++), il génère 14 380,923 octets de sortie d’erreur après 4½ minutes de temps CPU et un pic d’environ 100 Mio d’utilisation de la mémoire.Basé sur un rapport longueur de message / longueur de code, ceci peut être la meilleure solution:
Message (81):
81/0 = Inf
la source
279 caractères
Avec gcc 4.2.1, génère l’erreur
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘foofoo....foofoo’
avec 2 ^ 21 copies defoo
. 6 291 558 octets en tout. C'est à peu près le plus gros identifiant possible, remplacerfoo
parfood
génère un ICE.la source
#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)
. Cela me donne un message d'erreur à peu près aussi long avec beaucoup moins de code, et grandit beaucoup plus rapidement avec l'augmentation du motif dans n'importe quelle dimension, puisque nous implémentons essentiellement la fonction Ackermann.Similaire à VJo:
a.cpp:
g ++ a.cpp
produit beaucoup de sortie (au moins 2 gigaoctets avant que je ne le tue)
la source
Le code suivant est basé sur une erreur réelle que j'ai rencontrée une fois.
(en utilisant gcc)
La récursion des modèles est assez évidente, mais puisque j'ai utilisé
ftemplate-depth=100000
cette exécution, cela ne produit pas d'erreur. La source réelle des messages d'erreur provient dechar baz[i];
, ce qui produit une erreur lorsque la valeuri
tombe à -1.Après environ une demi-heure, je suis assis sur 21 000 erreurs de compilateur , 300 000 lignes de messages d'erreur et 280 mégaoctets de RAM utilisés par le compilateur. Et cela ne montre aucun signe d'arrêt.
MODIFIER:
Une heure plus tard, avec 36 000 erreurs de compilateur , 504 000 lignes de messages d'erreur et 480 mégaoctets de RAM ... et toujours en cours.
EDIT # 2:
Environ une demi-heure plus tard:
Statistiques finales: 38 876 erreurs de compilateur , 544 624 lignes de messages d’erreur, totalisant 48,8 Mo de données et 518,9 Mo de RAM utilisés par le compilateur avant qu’il ne tombe en panne.
la source
28 octets
Saboter la bibliothèque standard:
Utiliser Clang sur OS X 10.9:
456 lignes d'erreurs, 50 erreurs et une erreur de segmentation du compilateur !
Version Clang:
la source
Je suis tombé sur cela par accident:
Sur c ++ x11, il produit 44 ko de messages d'erreur, dans lesquels le compilateur essaie de dire: Veuillez définir un espace réservé pour le premier argument si vous le définissez pour le second.
Voir sur ideone .
la source
C ++
Basé sur la solution de BЈовић:
Fichier: golf.cpp:
Exécuter ceci sous G ++ ne se terminera pas, cependant, j’ai calculé la longueur de l’erreur qu’il émettrait éventuellement d’environ 85 * 2 ^ 140 téraoctets.
la source
Modèles variadiques C ++ 11 (69 caractères)
En configurant la profondeur maximale d’instantation du modèle, vous pouvez définir la longueur de l’erreur. Voici un exemple d'utilisation de GCC 4.8.1 avec une profondeur de modèle par défaut (900):
Vous pouvez également ajouter dix caractères supplémentaires et utiliser un dépassement de nombre entier non signé pour augmenter la longueur de l'erreur:
Voici un exemple courant chez ideone.
la source
82 octets: celui-ci fonctionne de manière similaire à l'approche de Joey Adams , mais le message d'erreur augmentera de manière exponentielle par rapport à
-ftemplate-depth
(carstd::set<T>
c'est en faitstd::set<T, std::less<T>, std::allocator<T>>
).Pour
(x = -ftemplate-depth) >= 28
, il y aura 1460 × 3 x-27 + 269x - 5381 octets de messages d'erreur (compilé par gcc 7.2.0). Autrement dit, dans les paramètres par défaut (x = 900), il générera théoriquement environ 4,9 × 10 419 octets de message d'erreur .Notez que sans l’
return
instruction, les messages d’erreur ne seront produits qu’à la fin de la compilation. (Ainsi, dans les paramètres par défaut, vous ne recevrez pas les messages - vous manquerez d’abord de mémoire.)Avertissement: La compilation de ce programme consomme beaucoup de mémoire.
Essayez-le en ligne!
la source
map
semble strictement plus mal, carstd::map<T,T>
eststd::map<T,T,std::less<T>,std::allocator<std::pair<T,T>>>
ainsi vous obtenez récursion 5 voies au lieu de 3, pour seulement 2 plus d' octets.-ftemplate-depth=13
, 423 572 octets-ftemplate-depth=14
et 1 247 322 octets-ftemplate-depth=15
.map
variante génère 13 373 990 octets à la profondeur 14 et 66 759 871 octets à la profondeur 15.-ftemplate-depth=1024
, ce qui signifie quelque part au nord de 10 ^ 713 octets avec lamap
variante. Je crois que cela signifie que vous gagnez ...Cela produit une sortie infinie sur GCC 5.2 et Clang 3.6 (nécessite Clang
-ferror-limit=0
, GCC fonctionne avec les paramètres par défaut):la source
Un fichier nommé
a.cpp
. Code:Ceci est une bombe à fourche où n = 40.
la source
=>
=>
compiler avec
index_sequence semble contourner le problème de limite de profondeur d'instanciation du modèle
les erreurs ressemblent à ceci: la séquence entière de 0 ... C-1 ressemble à une impression 4 fois * C
et les séquences de nombres peuvent aller au-delà de la limite de profondeur d'instanciation de modèle par défaut, certainement parce que cela est intégré:
la source