Soy desarrollador y no tengo ganas de hacer mi trabajo. Sé por XKCD que la mejor excusa para aflojar es que su código está compilando . ¡Debido a esto, creo que necesito un código que se compilará para siempre! Y debido a que soy flojo y no quiero tener que escribir mucho, esto tiene que hacerse con el código más corto posible.
Entonces, su tarea es escribir un programa que sea sintácticamente válido, pero hará que el compilador ingrese un bucle infinito.
Especificaciones
- Debe usar un lenguaje que tenga un compilador, obviamente.
- Especifique la implementación utilizada en cada solución.
- Este es el código de golf , por lo que gana la solución válida más corta (en bytes).
- El compilador puede terminar por quedarse sin memoria o espacio de pila.
code-golf
compile-time
Fruta Esolanging
fuente
fuente
Java
: definir un procesador de anotaciones (fragmento de ideona) que usará al invocarjavac
con su-processor
opción. Hace que la compilación de cualquier clase se cuelgue para siempre.Respuestas:
Japt , 2 bytes
Puede probar esto en línea aquí , pero no lo recomendaría, ya que congelará su navegador.
Explicación
Japt usa la biblioteca shoco para comprimir cadenas. Un backtick le dice al compilador que descomprima todo hasta el siguiente backtick o al final del archivo. Cada byte hace lo siguiente:
00-7F
se dejan intactos80-BF
cada transforman en un par de dos letras minúsculas común (at
,oo
,th
, etc.).C0-DF
cada uno consume el siguiente byte y se transforma en una cadena común de cuatro letras .E0-EF
cada uno consume los siguientes tres bytes y se transforma en una cadena de ocho letras "común" (que comienzaWhererer
y desciende desde allí).F0-F7
rompa el descompresor, aunque todavía devuelve todo al byte de ruptura.F8-FF
hacer que el descompresor entre en un bucle infinito. No estoy seguro de por qué es así, ya que no estoy muy familiarizado con el funcionamiento interno de la biblioteca shoco (y el código JavaScript es completamente ilegible ), pero es bastante útil en este caso.No creo que haya otra forma de meterse con el compilador de Japt, pero nunca se sabe ...
fuente
TikZ (pdfTeX 3.14159265-2.6-1.40.17),
857974242221 bytesUn montón de bytes guardados gracias a wchargin
Un byte guardado gracias a Chris H
En realidad me encontré con este por accidente cuando estaba trabajando en la tarea. Pasé bastante tiempo esperando que se compilara antes de darme cuenta de lo que estaba sucediendo.
Esto tiene dos partes:
Esto carga el paquete TikZ
y:
Esto inicia un
\tikz
entorno y un comando de dibujo.Que esta pasando
El compilador pdflatex tiene problemas
\tikz\pic
y entra en modo interactivo, lo que hace que se detenga indefinidamente.fuente
\draw l\end {document}
archivo finalizó al escanear el uso de\tikz@next.
" pdflatex 3.1415926-2.5-1.40.14 (TeX Live 2013 / Debian). tikz 13/10/2010 v2.10. Esto es estándarapt install texlive-full
en Ubuntu 14.04.pdfTeX 3.14159265-2.6-1.40.17 (TeX Live 2016)
y, de hecho, se repite indefinidamente. Gracias por los consejos.\pic
lugar de \ draw` - exactamente el mismo comportamiento (probado usando tikz 1.142)\def\a{\a}\a
(12 bytes)? O, como este es el código de golf y~
está activo por defecto,\def~{~}~
(9 bytes)C, 18 bytes
Los compiladores generalmente se rendirán después de recurrir unas 200 veces.
¿La construcción DOM cuenta como un paso de compilación? Si es así, entonces
x.htm
:fuente
<?include __FILE__;
.Java,
10295898878 bytesEsto termina con lo
StackOverflowError
que sucede porque el sistema de resolución genérico no puede decidir una raíz contra la cual resolver los otros genéricos.Créditos donde vencen .
¿Qué pasa aquí?
A<T>
está ahí para tener un padre de 1 letra. Es genérico Podría haberlo usadoList
, pero las importaciones y la repetición de 4 letras son demasiado largas.B<T>
declara un genérico básico.B extends A
se requiere tener una jerarquía entreB
yA
.extends A<A>
crea una auto referencia enA<T>
.A<? super B>
desencadena la búsqueda de genéricos enA<T>
B<B<T>>
crea una autorreferencia enB<T>
.A<...> a=new B<>()
fuerza el uso de los genéricos, en lugar de simplemente la definición de los mismos, forzando la resolución al compilarB
, y no después.A<?super B
crea una no referencia propia, por lo que tenemos una referencia a un tipo y a otro en los genéricos deA
.B<A>
crea una no referencia propia, por lo que tenemos una referencia a un tipo y a otro en los genéricos deB
.Ahora, el tipo
A
tiene tipo genéricoA
yB
, pero ¿cuál se debe elegir? Olvídate de ti mismo, tratemos de resolverloB
. Silbido.De acuerdo, ¿
B
tiene tipo genéricoA
yB
, pero cuál elegir? Olvídate de ti mismo, tratemos de resolverloA
. Apestar.Este tipo de recursividad en realidad no puede ser evitado porque hay casos legítimos como
A<B<A<B<A<B<Object>>>>>>
: por ejemplo, un objeto JSON:List<Map<String,Map<String,List<Map<String,List<String>>>>>>
.Resultado de compilación
En mi sistema, el seguimiento de la pila se detiene después de mostrar 1024 líneas, que en realidad son las 4 mismas líneas repetidas 256 veces, lo que demuestra una recursión infinita. Te ahorraré todo ese rastro.
Ahorros
interface
+implements
conclass
+extends
.Long
conA
(dos veces).new B<A>()
→new B<>()
).fuente
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>b=new B<>();}
B
contiene una referencia indecidible al genérico,A
que a su vez contiene una referencia indecidible al genérico de B. Cuando el resolutor no puede decidir, verifica las referencias incluidas, pero aquí ambos genéricos se refieren entre sí de una manera indecidible (principalmente gracias a las auto-referencias y lasuper
palabra clave. Por lo tanto, el solucionador realmente hace ping-pong entre los dos genéricos.public @interface X {@X(x=X.class)Class<? extends X> x();}
... Pero rápidamente me di cuenta de por qué eso no funcionaría jajaja.GNU Makefile,
87 bytesUn byte guardado gracias a KonradRudolph
Guardado como
Makefile
e invocado pormake
:Esto producirá una recursión de construcción infinita en el primer objetivo encontrado
"x"
.No hace falta decir que realmente no desea ejecutar esta bomba tenedor en su servidor de producción. :-)
Versión alternativa, 5 bytes.
Sugerido por KonradRudolph:
$_
es una referencia al último argumento del comando anterior. Más específicamente, se resuelve aquí como la ruta absoluta al comando que se está ejecutando, que es enmake
sí mismo.Esto debería funcionar bien en un entorno Bash genuino, pero no en Windows + MinGW.
fuente
make
que realmente compile el Makefile (solo lo interpreta).C ++,
6058Esto crea instancias recursivamente
class a
con diferentes parámetros de plantilla. GCC 7.0 se detiene después de 900 niveles de recursión con toneladas de errores sobreoperator->
ser privado pero, por ejemplo, ICC 17 y Microsoft (R) C / C ++ Optimizing Compiler 19 se agotan en Godbolt .El problema con eso es que probablemente todos los compiladores se quedarán sin memoria en algún momento, por lo que incluso sin límites de recursión, esto se detendrá. Lo mismo probablemente se aplica a la respuesta Clojure, también.
Editar: 2 bytes guardados por bolov - Gracias
fuente
a<int>i=i->b;
operator->
predeterminado es privado dentro de una clase. Dentro de una estructura es pública y, pori->b
lo tanto, puede acceder a ella.Perl ,
1513 bytesPruébalo en línea!
Ahora con 2 bytes guardados: @Zaid me recordó una forma terser de hacer un bucle en Perl.
Esto es bastante simple: simplemente instala un gancho de analizador con un bucle infinito, lo que hace que el código tarde infinitamente en analizar. (Perl es bueno porque le permite ejecutar código arbitrario en el medio del análisis; los ganchos del analizador se especifican en el propio Perl y se usan con frecuencia para hacer cosas como importar bibliotecas o cambiar las reglas de análisis para un identificador que desee tratar como una palabra clave.) ¡Pruébelo en línea! el enlace de arriba ofrece la
-c
opción (compilar el código para verificar la sintaxis de la corrección, pero no ejecutarlo), para probar que el bucle infinito ocurre en tiempo de compilación.En caso de que se esté preguntando acerca del "tiempo de compilación" en un lenguaje de scripting: Perl realmente compila en bytecode y luego ejecuta el bytecode, pero este es un detalle que rara vez es relevante al programarlo. La
-MO=
familia de opciones de línea de comando se puede usar para hacer cosas con el código de bytes además de ejecutarlo (aunque no con este programa, ya que el bucle infinito ocurre antes de que se pueda generar el código de bytes).fuente
a:goto a
también se ve bien (tristemente el mismo bytecount).BEGIN{{redo}}
te ahorrará algunos bytesC ++,
373029 bytesUtiliza el futuro parámetro de función automática. Se propuso en C ++ 17, pero no creo que lo haya logrado.
gcc
Sin embargo, lo admite como una extensión.Básicamente
es equivalente a
El código intenta crear instancias
f
recursivamente con diferentes argumentos de plantilla.gcc
falla conCon
-ftemplate-depth=10000
eso lo escupí "Asesinado: tiempo de procesamiento excedido" en godbolt.Compruébalo en godbolt
1 byte guardado por Quentin. Gracias.
fuente
int
como tipo de retorno :)auto
parámetros de la función no llegaron a C ++ 17; y tampocoint f() { ... }, a;
es una declaración legal la última vez que lo revisé. (No puede mezclar declaraciones de funciones con declaraciones de variables como esa). Lo que tiene aquí es un dialecto de C ++ extremadamente específico de GCC. No es que haya nada malo con eso en este contexto. :)Lisp común, 8 bytes
El compilador intentará leer un formulario y se encontrará con la macro del lector de puntos de sharpsign , que evalúa el código en el momento de la lectura y utiliza su resultado como el formulario para compilar. Aquí, el código que se ejecuta es un bucle infinito.
fuente
TeX, 9 bytes
TeX funciona expandiendo macros. La mayoría de las veces, las macros de TeX (también llamadas secuencias de control ) tienen la forma
\name
pero también es posible definir ciertos caracteres como macros, estos se llaman caracteres activos . El carácter~
está activo de forma predeterminada en TeX simple y, por lo tanto, se puede utilizar como un nombre de macro sin más declaraciones. El\def~{~}
en lo anterior define~
para que se expanda a~
. Es decir, cada vez que TeX se encuentra~
, lo reemplaza por~
y luego vuelve a examinar el reemplazo, lo que significa que encuentra una ocurrencia completamente nueva~
y lo reemplaza por~
. Esto define el bucle infinito. Todo lo que se necesita es comenzar el ciclo y eso es lo que hace el final~
.Agregado en editar
Para hacer esto correctamente compilado , invoque como:
La
-ini
bandera dice quepdftex
debería compilar un nuevo archivo de formato. Este es un conjunto de definiciones precompiladas que se pueden cargar cuando se invoca TeX más tarde para acelerar el procesamiento de un documento (LaTeX2e es un ejemplo de esto). Supongo que&pdftex
agrega algunos bytes, llevando el total a 17.fuente
pdftex
programa como "interpretando" la entrada de TeX para producir un PDF como "salida", de la misma manera que elg++
programa "interpreta" la entrada de C ++ para producir un archivo .exe como "salida". ;)Haskell, 25 + 17 = 42 bytes
Un metaprograma simple de Haskell que define un valor infinito e intenta calcular ese valor en tiempo de compilación.
Invoque con
ghc -XTemplateHaskell <file.hs>
(+17 para el parámetro al compilador)fuente
$(let a=a in a)
No funciona (para 32 bytes)?let a = a in a
se reescribe en una excepción, lo que simplemente provoca un error del compilador en lugar de un bucle infinito. (aunque tal vez esto funcionaría con un compilador Haskell diferente, pero no tengo uno para probar)Exception when trying to run compile-time code: <<loop>>
, tanto en el intérprete como al compilar ... técnicamente, el código anterior también muere con una excepción, pero un desbordamiento de pila, que está explícitamente permitido por la especificación: y si tuvieras memoria infinita, realmente se repetiría para siempre. La<<loop>>
excepción se dispara mucho antes de que mi máquina se quede sin memoria.gradle,
109 bytescon el código anterior colocado en un
build.gradle
archivo. Gradle usa groovy como su lenguaje base, por lo que realmente estamos hablando de groovy aquí, pero como la pregunta era sobre el tiempo de construcción, pensé que gradle sería más apropiado.La ejecución de cualquier comando de compilación de Gradle con el código anterior imprime la línea de estado de compilación compatible con el jefe puntiagudo:
Si está buscando un aumento, agregue el
-d
indicador de depuración para:que además de verse impresionantemente complicado también se actualiza con un nuevo conjunto de:
líneas de estado cada 10 segundos, lo que hace que parezca que la compilación está ocupada haciendo importantes cosas técnicas ...
fuente
SWI-Prolog, 34 bytes
Explicación
term_expansion/2
es algo que el compilador llama automáticamente antes de compilar el código para transformar algunos términos del código fuente en otros.A continuación, se introduce una nueva regla para
term_expansion/2
:repeat,1=0.
.repeat/0
es un predicado que siempre tiene éxito y proporciona un número infinito de puntos de elección.1=0
está tratando de unificar1
con0
, que siempre esfalse
. Esto hará que el compilador retrocedarepeat
(ya que siempre proporciona un punto de elección) e intente1=0
nuevamente, etc.fuente
expand_term
en su lugar (como se diceterm_expansion
, no se puede usar como aquí en GNU Prolog). Sin embargo, no funciona conexpand_term
SWI.GNU Make, 44
No puedo reclamar crédito por esto. Se deriva del libro de Robert Mecklenburg Gestión de proyectos con GNU Make: El poder de GNU Make para construir cualquier cosa .
Prefiero esto a la otra respuesta de respuesta porque no utiliza la recursividad. En mi VM, la otra respuesta Make continúa los procesos de bifurcación y en algún lugar alrededor de 7,000 de profundidad, la VM se detiene por completo. Sin embargo, con esta respuesta puede continuar indefinidamente sin consumir recursos del sistema. Realmente podrás relajarte con esta construcción. He pasado más de 1,000,000 iteraciones sin degradación aparente del sistema.
Tenga en cuenta que tuve que agregar el
sleep 1
para que la marca de tiempo del archivo MAKE se actualice realmente cada vez. Puede cambiar estosleep 0.01
si desea que se queme a través de iteraciones un poco más rápido.fuente
GNU Forth, 15 bytes
Golfed
Vuelve a definir (vuelve a compilar) la palabra
:
e invoca un bucle infinito inmediato[do] [loop]
dentro de la nueva definición (justo en el momento de la compilación).¡Pruébelo en línea!
fuente
Clojure, 21 bytes
Vincula el compilador definiendo una macro que emite repetidamente llamadas para sí mismo.
En mi teléfono, esto hace que REPL se cuelgue y retrase el dispositivo. En mi computadora portátil, esto falla por completo con un StackOverflow.
Desafortunadamente, el StackOverflow ocurre instantáneamente, pero sigue siendo válido según las reglas.
fuente
MSBuild, 130 bytes
Guarde esto como un archivo con
.proj
extensión y ejecútelomsbuild
desde el símbolo del sistema. MSBuild ejecutará su único objetivo que simplemente genera otromsbuild
proceso.fuente
C, 31 bytes
Inspirado en el trauma digital . Compilar con la
-mcmodel=medium
bandera.Buena suerte compilando esto, necesitará 1.8 yottabytes de RAM y espacio en disco.
fuente
Mathematica 33 Bytes
El código intentará evaluar simbólicamente el argumento antes de la compilación, y el argumento en sí mismo es un bucle infinito. La función While tiene un segundo argumento nulo ya que no es importante.
fuente
Compile
llamada o antes?Haskell (GHC, sin Template Haskell o reglas de reescritura personalizadas) , 138
Teóricamente, esto entra en un bucle infinito de la misma manera que lo hace el enfoque de C ++ : el método polimórfico
y
se instancia a tipos cada vez más intrincados. En la práctica, el tamaño de pila asignado predeterminado se desborda rápidamente:Créditos a Luke Palmer .
fuente
Haskell (ghc), 32 + 2 = 34 bytes
correr con
ghc -O <file>
. Activa una regla de reescritura para la función principal que reescribe en la misma cosa. La única característica desafortunada es que ghc es lo suficientemente inteligente como para detectar esto y detenerse después de 100 iteraciones. No sé de una manera fácil de deshabilitar este comportamiento.fuente
Boo, 25 bytes
Esto define una macro, que se ejecuta en tiempo de compilación, que ejecuta un bucle infinito, y luego invoca la macro.
fuente
Óxido, 18 bytes
Clásico autoincluido. Sin embargo, Rustc es molestamente cuerdo, y por defecto se rescatará después de 128 recursiones, y se expande primero en profundidad, por lo que el crecimiento exponencial tampoco funciona. Sin embargo, lo mismo se aplica a las soluciones C y C ++.
fuente
Factor ,
2916La parte entre
<<
>>
se ejecuta en tiempo de análisis.En cuanto a que
[ t ] loop
hace, te dejaré adivinar ...Puede poner eso en el Listener tal cual, o agregarlo a cualquier vocabulario o archivo de script con el correspondiente material repetitivo.
fuente
PHP, 19 bytes
fuente