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.

nneonneo
источник
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);}
user75200
источник
И снова здравствуйте! Какая оригинальная программа не дает ошибок? (Я предполагаю, что это так 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.

user7291
источник
1
Даже если кажется, что это соответствует духу задачи (поскольку в заголовке указано «опечатка из одного символа»), это не следует правилу 2, которое гласит, что вы можете только добавить символ, но не удалять или изменять.
Джо Кинг,