Error tipográfico de 1 carácter que genera la mayoría de los mensajes de error de la compilación C ++

51

Parece que los cambios simples en un archivo C ++, especialmente con plantillas, pueden generar páginas de errores. Este concurso es para ver cuál es la mayor "explosión de dinero", es decir, la salida de error más detallada con el menor cambio en el código fuente (adición de 1 carácter).

Debido a que otros lenguajes son más sanos, esto se limitará a C ++ y gcc versión 4.x.

Reglas

  1. El archivo fuente original debe compilarse con gcc 4.9.2 al código objeto sin error.

  2. Se agrega un carácter ASCII al código fuente para crear un error tipográfico, aumentando el tamaño del archivo en 1 byte.

  3. El compilador se ejecuta con opciones predeterminadas. Las opciones necesarias como -cy -std=c++11están permitidas, las opciones como -Wallno.

  4. Métrica es

        number of bytes of generated error messages
        -----------------------------------------------------------------------
        (bytes of source code with typo) (length of filename passed to compiler)
    
  5. Las respuestas se validarán con http://ideone.com/ C ++ 4.9.2.

Ejemplo:

El nombre del archivo es a.cpp, que tiene 5 bytes de longitud.

int foo();

Compilación de trabajo

 gcc -c a.cpp

Código fuente dañado:

in t foo();

Compilación fallida

$ gcc -c a.cpp
a.cpp:1:1: error: ‘in’ does not name a type
in t foo();
  ^
$ gcc -c a.cpp |& -c wc
64
$ wc -c a.cpp
12 a.cpp

Puntuación: 64/12/5 = 1.0666

Mejor intento: insertar {entre padres defoo()

$ gcc -c a.cpp |& wc -c
497

Nueva puntuación: 497/12/5 = 8.283

¡Buena suerte!

ACTUALIZAR

Animo a las personas a ignorar la implementación recursiva. Eso técnicamente gana pero no está en el espíritu del concurso.

ACTUALIZACIÓN 2

Como muchas personas han notado, el concurso probablemente habría sido más interesante si el preprocesador C no estuviera permitido. Por lo tanto, me gustaría alentar a las personas a publicar soluciones que no utilizan comandos de preprocesador en absoluto. ¡Eso no implica el uso de ningún archivo de encabezado, ya #includeque no está permitido!

En cuanto a usar IDEONE para validar, puede usar la salida de IDEONE directamente (y el nombre de la fuente como prog.cpp), o puede ejecutar la salida de IDEONE a través de una búsqueda y reemplazo global ( s/prog.cpp/a.cc/por ejemplo) y pretender que pudo establecer el nombre del archivo directamente.

ACTUALIZACIÓN 3

Como señalaron las personas, Ideone es un poco demasiado restrictivo, requiere vinculación, no solo la creación de archivos de objetos. Como este concurso es puramente divertido, sea honesto y especifique lo que utilizó para obtener su puntaje. Use ideone o use la versión más vainilla (todos los valores predeterminados) de gcc 4.9.2 como pueda reunir. El concurso está destinado a dar a conocer la horror de los mensajes de error de C ++.

Mark Lakata
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat . Alternativamente, para discusiones sobre lo que debería o no contar como un duplicado , lleve la discusión a meta .
Martin Ender
Tres problemas con el uso de ideone para validar: fuerza el nombre del archivo de origen a "prog.cpp", trunca la salida de error del compilador a 64kB y enlaza, agregando errores adicionales. Por lo tanto, no será una buena herramienta de validación.
Jason C
He estado usando GCC 4.9.2 del repositorio de Ubuntu de prueba de cadena de herramientas.
nneonneo
¿Cuáles son las opciones predeterminadas? Hasta donde yo sé, puede configurar las opciones predeterminadas de gcc en tiempo de compilación.
FUZxxl
2
Trae recuerdos: desde alrededor de 1975, nuestro profesor de física realizó una competencia anual de "la mayoría de los errores de 10 (
punzones

Respuestas:

45

gcc 4.5.2, Puntuación: 8579.15 (o 14367.49 para el nombre de archivo "aC", puede actualizar más tarde)

Archivo original, 29 bytes, compila limpio (a.cpp):

#if 0
#include"a.cpp"
#endif

Archivo modificado, 30 bytes:

#iff 0
#include"a.cpp"
#endif

Errores:

$ gcc -c a.cpp 2>&1 | wc -c
1286873

Puntuación:

1286873 / (30 * 5) = 8579.15

Cabeza y cola de salida de error:

a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:

... And so on, backing out with second error after max include depth:

a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0:
a.cpp:3:2: error: #endif without #if
a.cpp:3:2: error: #endif without #if

Nota:
- Si .Ctermina calificando como una extensión válida , el puntaje es 1,206,869 / (28 * 3) = 14,367.49.
- Si se agrega el segundo #include sugerido por Dennis, nombre de archivo "a.cpp", el puntaje es 80,797,292,934 / (46 * 5) = 351,292,578.97

Jason C
fuente
2
La pregunta dice agregar un personaje, no reemplazarlo.
Dennis
3
@ Dennis Oh hombre. Tengo esto. Mira esta segunda edición. Tu comentario fue una bendición disfrazada.
Jason C
1
@ JasonC No puedo votar esto suficientes veces.
isaacg
99
Creo que puede reclamar una puntuación infinita si agrega un segundo #include"a.cpp".
Dennis
3
@ Dennis Whoa, ¡bien! Voy a dejar la respuesta tal como está, ya que no pensé agregar un segundo #includepor mi cuenta. En cuanto a que es infinito ... si todavía está funcionando cuando me levanto mañana por la mañana, es lo suficientemente infinito para mí. Los mantendré informados, ja (aunque, actualmente, está canalizando 5.1MB / seg wc, por lo que si estoy wcusando un contador de 32 bits, según mis cálculos, algo extraño puede suceder en aproximadamente 13 minutos)
Jason C
31

gcc 4.9.2, puntaje: 222,898,664 663,393,783

Esto se basa en gran medida en la respuesta de @ JasonC , pero dijo que no quería tomar el crédito por esta mejora.

La salida de error del código siguiente es de 126,044,818,789 bytes de longitud. La puntuación debería ser mucho más alta en teoría (y tender a infinito a medida que aumenta el número de declaraciones de inclusión), pero disminuye en la práctica al agregar más declaraciones de inclusión.

Archivo original (37 bytes)

/*#
#include"w.cpp"
#include"w.cpp"*/
$ gcc -c w.cpp
$

Archivo modificado (38 bytes)

/
*#
#include"w.cpp"
#include"w.cpp"*/
$ gcc -c w.cpp
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3,
                 from w.cpp:3:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3,
                 from w.cpp:3,
                 from w.cpp:3:
⋮
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
w.cpp:3:0: error: #include nested too deeply
 #include"w.cpp"
 ^
w.cpp:4:0: warning: extra tokens at end of #include directive
 #include"w.cpp"*/
 ^
w.cpp:4:0: error: #include nested too deeply
w.cpp:2: confused by earlier errors, bailing out
The bug is not reproducible, so it is likely a hardware or OS problem.
Dennis
fuente
66
Técnicamente, esto no producirá una salida infinita , aunque, con la tecnología informática actual (o previsible), no vivirás lo suficiente como para ver que se detenga. Básicamente, GCC tiene un #includelímite de anidamiento de 200 niveles, por lo que sus recursivos se #includeconvierten efectivamente en un contador binario de 200 bits.
Ilmari Karonen
3
Simplemente agregue más líneas de inclusión para obtener una puntuación infinita. El tamaño de salida crece más rápido que el código.
jimmy23013
Igualmente podría haberse basado en una de las respuestas de una pregunta anterior .
Peter Taylor
2
Se hizo terminar esta mañana, con un número enorme que comenzó con un 8, y que accidentalmente cerró la ventana antes de copiar el número , porque yo soy impresionante. Lo estoy ejecutando de nuevo.
Jason C
3
@JasonC También lo ejecuté y obtuve una salida de 77,877,399,160 bytes. Eso es mucho menos infinito de lo que esperaba, así que lo volveré a ejecutar con un nombre de archivo más corto.
Dennis
25

gcc, 4.9.2, Puntuación: 22.2

Archivo original: 0 bytes (a.cpp)

Compila limpio:

$ gcc -c a.cpp |& wc -c
0

Archivo modificado:

(

Errores:

$ gcc -c a.cpp |& wc -c
111

Puntuación

111/1/5 = 22.2

Mark Lakata
fuente
44
¿Ya forzaste esto brutalmente? Quiero decir, ¿es esta la puntuación más alta para un archivo de inicio de 0 bytes?
Thomas Weller
No, no hice fuerza bruta esto. Acabo de probar 3 o 4 personajes diferentes. Esta fue solo una respuesta inicial para que la gente se interesara en el concurso :)
Mark Lakata
23

11,126.95 9,105.44 2,359.37 1,645.94 266.88 puntos

¡Más abuso del preprocesador! Esta vez, estamos haciendo llorar a la biblioteca estándar.

Sin error tipográfico:

#define typedf
#include<fstream>

Con error tipográfico:

#define typedef
#include<fstream>

Errores:

In file included from /usr/include/c++/4.9/iosfwd:39:0,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/c++/4.9/bits/stringfwd.h:62:33: error: aggregate ‘std::basic_string<char> std::string’ has incomplete type and cannot be defined
   typedef basic_string<char>    string;   
                                 ^
/usr/include/c++/4.9/bits/stringfwd.h:68:33: error: aggregate ‘std::basic_string<wchar_t> std::wstring’ has incomplete type and cannot be defined
   typedef basic_string<wchar_t> wstring;   
                                 ^
/usr/include/c++/4.9/bits/stringfwd.h:78:34: error: aggregate ‘std::basic_string<char16_t> std::u16string’ has incomplete type and cannot be defined
   typedef basic_string<char16_t> u16string; 
                                  ^
/usr/include/c++/4.9/bits/stringfwd.h:81:34: error: aggregate ‘std::basic_string<char32_t> std::u32string’ has incomplete type and cannot be defined
   typedef basic_string<char32_t> u32string; 
                                  ^
In file included from /usr/include/wchar.h:36:0,
                 from /usr/include/c++/4.9/cwchar:44,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/stdio.h:48:25: error: aggregate ‘_IO_FILE FILE’ has incomplete type and cannot be defined
 typedef struct _IO_FILE FILE;
                         ^
/usr/include/stdio.h:64:25: error: aggregate ‘_IO_FILE __FILE’ has incomplete type and cannot be defined
 typedef struct _IO_FILE __FILE;
                         ^
In file included from /usr/include/c++/4.9/cwchar:44:0,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/wchar.h:106:9: error: ‘__mbstate_t’ does not name a type
 typedef __mbstate_t mbstate_t;
         ^
/usr/include/wchar.h:151:38: error: ‘size_t’ is not a type
     const wchar_t *__restrict __src, size_t __n)
                                      ^
/usr/include/wchar.h:159:38: error: ‘size_t’ is not a type
     const wchar_t *__restrict __src, size_t __n)
                                      ^
/usr/include/wchar.h:166:63: error: ‘size_t’ is not a type
 extern int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n)
                                                               ^
/usr/include/wchar.h:176:4: error: ‘size_t’ is not a type
    size_t __n) __THROW;
    ^
In file included from /usr/include/wchar.h:180:0,
                 from /usr/include/c++/4.9/cwchar:44,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/xlocale.h:42:9: error: ‘__locale_t’ does not name a type
 typedef __locale_t locale_t;
         ^
In file included from /usr/include/c++/4.9/cwchar:44:0,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/wchar.h:183:5: error: ‘__locale_t’ is not a type
     __locale_t __loc) __THROW;
     ^
/usr/include/wchar.h:186:6: error: ‘size_t’ is not a type
      size_t __n, __locale_t __loc) __THROW;
      ^
/usr/include/wchar.h:186:18: error: ‘__locale_t’ is not a type
      size_t __n, __locale_t __loc) __THROW;
                  ^
/usr/include/wchar.h:196:8: error: ‘size_t’ does not name a type
 extern size_t wcsxfrm (wchar_t *__restrict __s1,
        ^
/usr/include/wchar.h:207:9: error: ‘__locale_t’ is not a type
         __locale_t __loc) __THROW;
         ^
/usr/include/wchar.h:212:8: error: ‘size_t’ does not name a type
 extern size_t wcsxfrm_l (wchar_t *__s1, const wchar_t *__s2,
        ^
/usr/include/wchar.h:252:8: error: ‘size_t’ does not name a type
 extern size_t wcscspn (const wchar_t *__wcs, const wchar_t *__reject)
        ^
/usr/include/wchar.h:256:8: error: ‘size_t’ does not name a type
 extern size_t wcsspn (const wchar_t *__wcs, const wchar_t *__accept)
        ^
/usr/include/wchar.h:287:8: error: ‘size_t’ does not name a type
 extern size_t wcslen (const wchar_t *__s) __THROW __attribute_pure__;
        ^
/usr/include/wchar.h:306:8: error: ‘size_t’ does not name a type
 extern size_t wcsnlen (const wchar_t *__s, size_t __maxlen)
        ^

[RECORTE]

/usr/include/c++/4.9/bits/fstream.tcc:934:35: error: ‘cur’ is not a member of ‘std::ios_base’
    __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
                                   ^
/usr/include/c++/4.9/bits/fstream.tcc:934:50: error: ‘_M_mode’ was not declared in this scope
    __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
                                                  ^
/usr/include/c++/4.9/bits/fstream.tcc:941:25: error: ‘_M_state_last’ was not declared in this scope
    + _M_codecvt->length(_M_state_last, _M_ext_buf,
                         ^
/usr/include/c++/4.9/bits/fstream.tcc:944:15: error: ‘streamsize’ does not name a type
         const streamsize __remainder = _M_ext_end - _M_ext_next;
               ^
/usr/include/c++/4.9/bits/fstream.tcc:945:13: error: ‘__remainder’ was not declared in this scope
         if (__remainder)
             ^
/usr/include/c++/4.9/bits/fstream.tcc:949:35: error: ‘__remainder’ was not declared in this scope
         _M_ext_end = _M_ext_buf + __remainder;
                                   ^
/usr/include/c++/4.9/bits/fstream.tcc:951:25: error: ‘_M_state_cur’ was not declared in this scope
         _M_state_last = _M_state_cur = _M_state_beg;
                         ^
/usr/include/c++/4.9/bits/fstream.tcc:951:40: error: ‘_M_state_beg’ was not declared in this scope
         _M_state_last = _M_state_cur = _M_state_beg;
                                        ^
/usr/include/c++/4.9/bits/fstream.tcc:960:2: error: ‘_M_codecvt’ was not declared in this scope
  _M_codecvt = _M_codecvt_tmp;
  ^
/usr/include/c++/4.9/bits/fstream.tcc:960:15: error: ‘_M_codecvt_tmp’ was not declared in this scope
  _M_codecvt = _M_codecvt_tmp;
               ^
/usr/include/c++/4.9/bits/fstream.tcc:962:2: error: ‘_M_codecvt’ was not declared in this scope
  _M_codecvt = 0;
  ^

En mi máquina Ubuntu, g++-4.9 -std=c++11 -c a.Cgenera 1,101,568 gloriosos bytes de errores, para un puntaje de 1101568/33/3 = 11,126.95.

nneonneo
fuente
77
Debería escribir un programa para analizar todos los encabezados estándar y determinar cuál #definele da más puntos.
Jason C
1
Puede empeorarlo aún más si lo reemplaza typedefpor t;. Ahora no solo interrumpe cada uso, typedefsino que también recibe una tonelada de errores "t no nombra un tipo". O %;para producir el "id. No calificado esperado antes del token%".
MSalters
1
#define typename *y #define int class stdparecía generar muchos más errores.
jimmy23013
11

62,93 puntos

Solo un poco de C ++ meta black magic, compilado con g++-4.8 -c -std=c++11 a.cc:

#include<memory>
template<int n>class B:std::unique_ptr<B<n-1>>{};template<>class B<0>{};B<-1>x;

Sin golf:

#include <memory>

template<int n>
class B: std::unique_ptr<B<n-1>> {};

template<>
class B<0> {};

B<-1>x;

G ++ tiene un límite de recursión de 900, por lo que cambiar B<1>a B<-1>un rango de 31 bits tiene un ... efecto interesante.

  • 96 bytes de código (sin contar el final que \nalgunos editores de texto agregan automáticamente, vimno lo hace).
  • Nombre de archivo de 4 letras, a.cc
  • 24165 bytes de mensaje de error, y está truncado. El mensaje de error completo tiene 1235889 bytes de contenido. Requeriría el -ftemplate-backtrace-limit=0cambio. ¡También significaría 3185 puntos para mí!

std::unique_ptr es solo la clase de plantilla que logra emitir el mensaje de error más largo, encontrado por prueba y error y conocimiento del STL y gatos y demás.

Stefano Sanfilippo
fuente
2
Pero ... ¿cómo puedo deshacerme de 6 espacios en blanco cuando solo tengo 3 en el código, @JasonC!
Stefano Sanfilippo
7

Puntuación 7.865

Estrictamente hablando, la respuesta de 0 bytes NO es correcta, ya que ideone.com se negará a compilar el archivo sin error. Lo mismo ocurre con el ejemplo int foo();: no se compilará en ideone.com (no puedo comentar debido a la falta de reputación ...)

Entonces, el programa más pequeño posible para compilar sin ninguno #includeses este:

int main(){}

Si cambia esto al siguiente código, fallará con 409 bytes de código de error (después de cambiar el nombre de prog.cpp a a.cc desde la salida de ideone.com):

int main(){[}

409 / (13 * 4) = 7.865

Actualice la pregunta en consecuencia, ya que los ejemplos dados no respetan las reglas dadas ...

Stefan M
fuente
1
Todo el asunto ideone es todo tipo de tonto.
Jason C
Estoy de acuerdo, agregué la regla de ideona después de que se publicó la pregunta y se dieron las primeras respuestas. Cat ya está fuera de la bolsa.
Mark Lakata
1

C, nombrado como .cc

main(){constexprs a(){*(int*)0=f;}a(0)}

Código de error:

.code.tio.cpp: In function ‘int main()’:
.code.tio.cpp:1:8: error: ‘constexprs’ was not declared in this scope
 main(){constexprs int a(f){*(int*)0=f;}a(0);}
        ^~~~~~~~~~
.code.tio.cpp:1:8: note: suggested alternative: ‘__cpp_constexpr’
 main(){constexprs int a(f){*(int*)0=f;}a(0);}
        ^~~~~~~~~~
        __cpp_constexpr
.code.tio.cpp:1:40: error: ‘a’ was not declared in this scope
 main(){constexprs int a(f){*(int*)0=f;}a(0);}
user75200
fuente
¡Hola de nuevo! ¿Cuál es el programa original que no falla? (Asumo que lo es main(){}, pero no estoy seguro) Además, ¿no es esto solo una mejora de la respuesta anterior? Si bien ciertamente puede mantener esta respuesta, si se inspiró en la respuesta de @ StefanM, debe mencionar eso. Finalmente, ahora que tiene 50 repeticiones, puede comentar en cualquier lugar.
NoOneIsHere
Creo que esto está demasiado cerca de la respuesta de Stefan M. Publicaría esto como una mejora recomendada para esa solución. Dicho esto, se permiten respuestas duplicadas. Sin embargo, ponga el original aquí y mencione cualquier inspiración (aunque también es posible que haya llegado a esto de forma independiente)
HyperNeutrino
1

Puntuación 12.xx (error al BORRAR un personaje)

Perdone la ruptura de la Regla 2 (en mi humilde opinión, agregar o eliminar un carácter estaría en el espíritu de la regla), pero esto me sucedió accidentalmente (por lo tanto, no utiliza ningún truco abusivo 'intencionalmente') al escribir Real Code (TM) - tanto el código que funciona como el que causa errores son (o parecen) simples y directos, así que pensé que era lo suficientemente ordenado como para incluirlos aquí. Código original

#include <iostream>
using namespace std;
int main ()
{
cout<<"test"<<endl;
}

Código que genera el error (último '<' eliminado, por lo que parece una comparación menor que, pero noooooooooooo ...)

#include <iostream>
using namespace std;
int main ()
{
cout<<"test"<endl;
}

Son "solo" 8241 bytes de mensajes de error del compilador en ideone.com g ++ 4.3.2.

usuario7291
fuente
1
Incluso si parece estar en el espíritu del desafío (ya que el título dice "error tipográfico de un personaje"), esto no sigue la regla 2 que dice que solo puede agregar un personaje, no eliminarlo o cambiarlo.
Jo King