Escribir un programa corto, que generaría el mensaje de error más largo posible, en un compilador de C ++ estándar ( gcc
, cl.exe
, icc
, o clang
).
La puntuación de cada entrada es el número de caracteres en el mensaje de error más largo que emitió el compilador. Los tipos incluidos en su código fuente y citados por el compilador se cuentan como un solo carácter.
Engañando
Siempre puede redefinir una plantilla en plantilla en plantilla con nombres largos, pero espero algo creativo. Traté de evitar algo de eso con la última regla, pero, por supuesto, las reglas pueden ser mejores, y me alegraré de las mejoras.
code-challenge
c++
error-message
Elazar Leibovich
fuente
fuente
Error.message.length / code.length
.Respuestas:
Los mensajes de error de plantilla son divertidos para descifrar. Considera esto:
Compilando con
gcc -c error.cpp
(4.6.3) producirá 15786 bytes de salida, con una línea más larga de 330 caracteres.Editar 2016-04-29: gcc 5.3.0 lo mejoró un poco: solo 9300 bytes, la línea más larga tiene 361 caracteres de longitud ...
Editar 2019-04-04: gcc 6.5.0: 11237 bytes, pero da algunas pistas sobre el error, como en estas líneas:
fuente
19 caracteres
Crea un archivo
a.cpp
con este contenido:Compilar como:
y obtenga increíbles mensajes de error de 21300 líneas :
...
... 21280 líneas de error ...
...
fuente
#include __FILE__
un nombre de archivo muy largo ...?clang++ -ferrorlimit=1000 a.cpp
. La línea más larga tiene 466 caracteres.98 (necesarios) caracteres:
Produce la siguiente salida de error en GCC (4.4.5):
Estadística:
Sin golf (produce una salida más larga):
Descubrí esto cuando quería ver si C ++ admite la recursividad polimórfica (y, como puede ver claramente, no lo hace). Aquí hay un ejemplo trivial de recursión polimórfica en Haskell:
Aquí, esto requiere Haskell actuar como tal instancia
Show x
,Show [x]
,Show [[x]]
,Show [[[x]]]
, ad infinitum. Haskell lo hace convirtiendo(Show x) =>
en un parámetro implícito a la funciónf
agregada por el compilador, algo como esto:C ++ lo hace intentando literalmente construir tales instancias hasta que se excede la profundidad de creación de instancias de plantilla.
fuente
cl
no le gusta implícitoint
en modo C ++) genera 14.380.923 bytes de salida de error después de 4½ minutos de tiempo de CPU y un pico de aproximadamente 100 MiB de uso de memoria.Según una relación de longitud de mensaje / longitud de código, esta puede ser la mejor solución:
Mensaje (81):
81/0 = Inf
fuente
279 caracteres
Con gcc 4.2.1, genera el error
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘foofoo....foofoo’
con 2 ^ 21 copias defoo
. 6.291.558 bytes en total. Es casi tan grande como un identificador que puedo conseguir, reemplazandofoo
confood
genera un ICE.fuente
#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)
. Esto me da un mensaje de error casi siempre con mucho menos código, y crece mucho más rápido al aumentar el patrón en cualquier dimensión, ya que esencialmente estamos implementando la función Ackermann.Similar a VJo:
a.cpp:
g ++ a.cpp
produce mucha salida (al menos 2 gigabytes antes de matarlo)
fuente
El siguiente código se basa en un error real que encontré una vez.
(usando gcc)
Recursión de plantilla bastante obvia, pero como utilicé
ftemplate-depth=100000
para esta ejecución, esto no produce un error. La fuente real de los mensajes de error provienechar baz[i];
, lo que produce un error cuandoi
cae a -1.Después de aproximadamente media hora, estoy sentado con 21,000 errores de compilación , 300,000 líneas de mensajes de error y 280 megabytes de RAM utilizados por el compilador. Y no muestra signos de detenerse.
EDITAR:
Una hora más tarde, ahora con 36,000 errores de compilación , 504,000 líneas de mensajes de error y 480 megabytes de RAM ... y sigue funcionando.
EDITAR # 2:
Aproximadamente media hora después:
Estadísticas finales: 38.876 errores del compilador , 544.624 líneas de mensajes de error, un total de 48,8 megabytes de datos y 518,9 megabytes de RAM utilizados por el compilador antes de que se bloqueara.
fuente
28 bytes
Sabotear la biblioteca estándar:
Usando clang en OS X 10.9:
¡456 líneas de errores, 50 errores y un compilador segfault !
Versión de Clang:
fuente
Me topé con esto por accidente:
En c ++ x11 produce 44 kb de mensajes de error, en los que el compilador intenta decir: defina el marcador de posición para el primer argumento si lo define para el segundo.
Véalo en ideone .
fuente
C ++
Basado en la solución de BЈовић:
Archivo: golf.cpp:
Ejecutar esto en G ++ no terminará, sin embargo, he calculado la longitud del error que eventualmente emitirá como aproximadamente 85 * 2 ^ 140 terabytes.
fuente
C ++ 11 plantillas variadas (69 caracteres)
Al configurar la profundidad máxima de instauración de la plantilla, puede establecer la longitud del error. Aquí hay un ejemplo usando GCC 4.8.1 con profundidad de plantilla predeterminada (900):
También podría agregar diez caracteres más y usar un flujo inferior de entero sin signo para aumentar la longitud del error:
Aquí hay un ejemplo que se ejecuta en ideone.
fuente
82 bytes: este funciona de manera similar al enfoque de Joey Adams , pero el mensaje de error crecerá exponencialmente con respecto a
-ftemplate-depth
(porque enstd::set<T>
realidad lo esstd::set<T, std::less<T>, std::allocator<T>>
).Para
(x = -ftemplate-depth) >= 28
, habrá 1460 × 3 x-27 + 269x - 5381 bytes de mensajes de error (compilados por gcc 7.2.0). Es decir, en la configuración predeterminada (x = 900), generará aproximadamente 4.9 × 10 419 bytes de mensaje de error teóricamente.Tenga en cuenta que sin la
return
declaración, los mensajes de error solo se generarán al final de la compilación. (por lo tanto, en la configuración predeterminada no recibirá los mensajes; primero se quedará sin memoria).Advertencia: compilar este programa consumirá mucha memoria.
Pruébalo en línea!
fuente
map
parece estrictamente más malo, ya questd::map<T,T>
esstd::map<T,T,std::less<T>,std::allocator<std::pair<T,T>>>
así que obtienes una recursión de 5 vías en lugar de 3, por solo 2 bytes más.-ftemplate-depth=13
, 423,572 bytes a-ftemplate-depth=14
y 1,247,322 bytes a-ftemplate-depth=15
.map
la variante genera 13,373,990 bytes a la profundidad 14 y 66,759,871 bytes a la profundidad 15.-ftemplate-depth=1024
, lo que significa en algún lugar al norte de 10 ^ 713 bytes con lamap
variante. Creo que esto significa que ganas ...Esto produce una salida infinita en GCC 5.2 y Clang 3.6 (en Clang requiere
-ferror-limit=0
, en GCC funciona con la configuración predeterminada):fuente
Un archivo llamado
a.cpp
. Código:Esta es una bomba tenedor donde n = 40.
fuente
=>
=>
compilar con
index_sequence parece omitir el problema de límite de profundidad de instanciación de plantilla
los errores se ven así: toda la secuencia de números 0 ... C-1 parece que se imprime 4 * C veces
y las secuencias numéricas pueden superar el límite de profundidad de creación de instancias predeterminado de la plantilla, ciertamente porque es una función integrada:
fuente