1-символьная опечатка, генерирующая большинство сообщений об ошибках из компиляции C ++


51

Кажется, что простые изменения в файле C ++, особенно с шаблонами, могут генерировать страницы ошибок. Этот конкурс состоит в том, чтобы увидеть, какой самый большой «удар доллара», то есть более подробный вывод ошибок с наименьшим изменением исходного кода (добавление 1 символа).

Поскольку другие языки более разумны, это будет ограничено C ++ и gcc версии 4.x.

правила

  1. Исходный исходный файл должен компилироваться с gcc 4.9.2 в объектный код без ошибок.

  2. Один символ ASCII добавляется в исходный код для создания опечатки, увеличивая размер файла на 1 байт.

  3. Компилятор запускается с параметрами по умолчанию. Необходимые опции как -cи -std=c++11разрешены, опции как -Wallнет.

  4. Метрика есть

        number of bytes of generated error messages
        -----------------------------------------------------------------------
        (bytes of source code with typo) (length of filename passed to compiler)
    
  5. Ответы будут проверены с http://ideone.com/ C ++ 4.9.2.

Пример:

Имя файла составляет a.cpp5 байтов.

int foo();

Рабочая подборка

 gcc -c a.cpp

Поврежденный исходный код:

in t foo();

Неудачная компиляция

$ 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

Оценка: 64/12/5 = 1,0666

Лучшая попытка: вставить {между скобкамиfoo()

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

Новый счет: 497/12/5 = 8,283

Удачи!

ОБНОВИТЬ

Я призываю людей игнорировать рекурсивную реализацию. Это технически выигрывает, но не в духе конкурса.

ОБНОВЛЕНИЕ 2

Как отмечали многие, конкурс, вероятно, был бы более интересным, если бы не был допущен препроцессор Си. Поэтому я хотел бы призвать людей публиковать решения, которые вообще не используют команды препроцессора. Это подразумевает, что никакие заголовочные файлы вообще не используются, поскольку #includeэто запрещено!

Что касается использования IDEONE для проверки, вам разрешено либо использовать выход IDEONE напрямую (и имя источника как prog.cpp), либо вы можете запустить вывод IDEONE через глобальный поиск и замену ( s/prog.cpp/a.cc/например) и притворяться, что вы смогли установить имя файла напрямую.

ОБНОВЛЕНИЕ 3

Как отмечали люди, Ideone слишком ограничен и требует связывания, а не просто создания объектного файла. Поскольку этот конкурс проводится исключительно во имя веселья, пожалуйста, будьте честны и укажите, что вы использовали, чтобы получить свой счет. Либо используйте ideone, либо используйте самую ванильную сборку (все значения по умолчанию) из gcc 4.9.2, которую вы можете собрать. Конкурс призван привлечь внимание к ужасным сообщениям об ошибках C ++.


Комментарии не для расширенного обсуждения; этот разговор был перемещен в чат . Кроме того, для обсуждения того, что следует или не следует считать дубликатом, перейдите к мета .
Мартин Эндер

Три проблемы с использованием ideone для проверки: он заставляет имя исходного файла «prog.cpp», усекает вывод ошибок компилятора до 64 КБ и связывает, добавляя дополнительные ошибки. Так что это не будет хорошим инструментом проверки.
Джейсон С

Я использую GCC 4.9.2 из репозитория Ubuntu для тестирования инструментов.
nneonneo

Каковы параметры по умолчанию? Насколько я знаю, вы можете настроить параметры по умолчанию для gcc во время компиляции.
FUZxxl

2
Возвращает воспоминания: примерно с 1975 года наш учитель физики проводил ежегодный конкурс «большинство ошибок из 10 (ручных) перфокарт Фортрана» ...
TripeHound

Ответы:


45

gcc 4.5.2, оценка: 8579,15 (или 14367,49 для имени файла «aC», возможно, обновится позже)

Исходный файл, 29 байт, компилируется в чистом виде (a.cpp):

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

Модифицированный файл, 30 байт:

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

Ошибки:

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

Гол:

1286873 / (30 * 5) = 8579,15

Голова и хвост вывода ошибки:

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

Примечание:
- Если в .Cконечном итоге квалификация в качестве действительного расширения, то оценка составляет 1 206 869 / (28 * 3) = 14 367,49.
- Если добавлен второй предложенный Денисом #include, имя файла "a.cpp", оценка 80,797,292,934 / (46 * 5) = 351,292,578,97


2
Вопрос говорит, чтобы добавить символ, а не заменить его.
Деннис

3
@ Деннис О, чувак. Я получил это. Смотрите это второе редактирование. Ваш комментарий был скрытым благословением.
Джейсон С

1
@JasonC Я не могу высказать это достаточно раз.
Исаак

9
Я думаю, что вы можете претендовать на бесконечное количество очков, если вы добавите секунду #include"a.cpp".
Денис

3
@ Деннис Вау, хорошо! Я собираюсь оставить ответ как есть, так как я не думал добавлять секунду #includeсамостоятельно. Что касается того, чтобы быть бесконечным ... если он все еще работает, когда я просыпаюсь завтра утром, это достаточно бесконечно для меня. Будем держать вас в курсе, ха (хотя, в настоящее время он использует 5.1 МБ / с wc, поэтому, если wcиспользуется 32-битный счетчик, по моим расчетам, через 13 минут может произойти что-то странное.)
Jason C

31

gcc 4.9.2, оценка: 222 898 664 663 393 783

Это в значительной степени основано на ответе @ JasonC , но он сказал, что не хочет брать кредит на это улучшение.

Ошибка вывода кода ниже составляет 126,044,818,789 байт. Оценка должна быть намного выше в теории (и стремиться к бесконечности по мере увеличения числа включаемых операторов), но на практике она уменьшается, добавляя больше включаемых операторов.

Исходный файл (37 байт)

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

Модифицированный файл (38 байт)

/
*#
#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.

6
Технически это не приведет к бесконечному выводу , хотя при современных (или прогнозируемых) компьютерных технологиях вы не проживете достаточно долго, чтобы остановить это. По сути, GCC имеет #includeпредел вложенности в 200 уровней, поэтому ваши рекурсивные #includes эффективно становятся 200-битным двоичным счетчиком.
Илмари Каронен

3
Просто добавьте дополнительные строки, чтобы получить бесконечный счет. Размер вывода растет быстрее, чем код.
jimmy23013

В равной степени это могло быть основано на одном из ответов на предыдущий вопрос .
Питер Тейлор

2
Он сделал закончить сегодня утром, с каким - то огромным количеством , которое началось с 8, и я случайно закрыл окно перед копированием номера , потому что я удивительный. Я снова запускаю это.
Джейсон С

3
@JasonC Я тоже запустил его и получил 77 7777 399 160 байт. Это намного менее бесконечно, чем я ожидал, поэтому я запусту его снова с более коротким именем файла.
Деннис

25

gcc, 4.9.2, оценка: 22.2

Исходный файл: 0 байт (a.cpp)

Компилирует чистый:

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

Измененный файл:

(

Ошибки:

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

Гол

111/1/5 = 22,2


4
Вы уже переборщили? Я имею в виду, это самая высокая оценка для 0-байтового файла запуска?
Томас Уэллер

Нет, я не грубой силой этого. Я только что попробовал 3 или 4 разных персонажа. Это был просто начальный ответ, чтобы заинтересовать людей в конкурсе :)
Марк Лаката

23

11 126,95 9 105,44 2 359,37 1 645,94 266,88 балла

Больше злоупотреблений препроцессором! На этот раз мы заставляем стандартную библиотеку плакать.

Без опечатки:

#define typedf
#include<fstream>

С опечаткой:

#define typedef
#include<fstream>

Ошибки:

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)
        ^

[СНиП]

/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;
  ^

На моей машине с Ubuntu g++-4.9 -std=c++11 -c a.Cгенерирует 1 101 568 великолепных байтов ошибок, для оценки 1101568/33/3 = 11 126,95.


7
Вы должны написать программу, которая проанализирует все заголовки std и определит, какие из них #defineдают вам наибольшее количество очков.
Джейсон C

1
Вы можете ухудшить его, заменив typedefна t;. Теперь вы не только отказываетесь от каждого использования, typedefно и получаете кучу ошибок "t not name a type". Или %;создать "ожидаемый неквалифицированный идентификатор перед% token".
MSalters

1
#define typename *и #define int class stdказалось, генерировать гораздо больше ошибок.
jimmy23013

11

62,93 балла

Просто немного мета-черной магии C ++, скомпилированной с 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;

Ungolfed:

#include <memory>

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

template<>
class B<0> {};

B<-1>x;

G ++ имеет предел рекурсии 900, поэтому переход B<1>на B<-1>31-битный диапазон имеет ... интересный эффект.

  • 96 байт кода (не считая финала, \nнекоторые текстовые редакторы автоматически добавляют, vimнет).
  • 4-х буквенное имя файла, a.cc
  • 24165 байт сообщения об ошибке, и оно усечено. В полном сообщении об ошибке содержится 1235889 байт контента. Это потребовало бы -ftemplate-backtrace-limit=0выключателя. Это также означало бы 3185 очков для меня!

std::unique_ptr это просто шаблонный класс, который может выдавать самое длинное сообщение об ошибке, найденное методом проб и ошибок и знанием STL, кошек и прочего.


2
Но ... как я могу избавиться от 6 пробелов, когда у меня только 3 в коде, @JasonC!
Стефано Санфилиппо

7

Оценка 7,865

Строго говоря, 0-байтовый ответ НЕ верен, так как ideone.com откажется компилировать файл без ошибок. То же самое верно для примера int foo();- он не будет компилироваться на ideone.com (я не могу комментировать из-за отсутствия репутации ...)

Таким образом, наименьшая возможная программа для компиляции без #includesтакова:

int main(){}

Если вы измените это на следующий код, он потерпит неудачу с 409 байтами кода ошибки (после переименования prog.cpp в a.cc из вывода ideone.com):

int main(){[}

409 / (13 * 4) = 7,865

Пожалуйста, обновите вопрос соответствующим образом, так как приведенные примеры не соответствуют данным правилам ...


1
Вся эта идеальная вещь - всякие глупости.
Джейсон С

Я согласен, я придерживался правила ideone после того, как вопрос был опубликован и даны первые ответы. Кошка вроде как из сумки.
Марк Лаката

1

С, названный как .cc

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

Код ошибки:

.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);}

И снова здравствуйте! Какая оригинальная программа не дает ошибок? (Я предполагаю, что это так main(){}, но я не уверен) Кроме того, не является ли это просто улучшением ответа выше? Хотя вы, конечно, можете сохранить этот ответ, если он был вдохновлен ответом @ StefanM, вы должны упомянуть об этом. Наконец, теперь, когда у вас есть 50 представителей, вы можете комментировать где угодно.
NoOneIsHere

Я думаю, что это слишком близко к ответу Стефана М.; Я бы опубликовал это как рекомендуемое улучшение для этого решения. При этом, повторные ответы разрешены. Пожалуйста, поместите оригинал здесь и
упомяните

1

Оценка 12.xx (ошибка при УДАЛЕНИИ символа)

Пожалуйста, прости за нарушение правила 2 (ИМХО добавление ИЛИ удаление одного символа было бы в духе правила), но это случилось со мной случайно (таким образом, не использует никаких «преднамеренно» оскорбительных трюков) при написании Real Code (TM) - и рабочий, и вызывающий ошибки код (или выглядят) простыми и понятными, поэтому я подумал, что это достаточно аккуратно, чтобы включить их здесь. Оригинальный код

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

Код, сгенерировавший ошибку (последний '<' удален, так что это выглядит как сравнение меньше, но noooooooooooo ...)

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

Это всего лишь 8241 байт сообщений об ошибках компилятора в ideone.com g ++ 4.3.2.


1
Даже если кажется, что это соответствует духу задачи (поскольку в заголовке указано «опечатка из одного символа»), это не следует правилу 2, которое гласит, что вы можете только добавить символ, но не удалять или изменять.
Джо Кинг,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.