Опечатка друку з символів генерує більшість повідомлень про помилки з компіляції 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

Як зазначають багато людей, змагання, ймовірно, були б цікавішими, якби попередній процесор C не був дозволений. Тому я хотів би заохотити людей публікувати рішення, які взагалі не використовують команди попереднього процесора. Це означає, що взагалі не використовуються файли заголовків, оскільки #includeце не дозволено!

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

ОНОВЛЕННЯ 3

Як зазначали люди, Ideone є занадто обмежуючим, вимагає посилання, а не просто створення об'єктних файлів. Оскільки цей конкурс суто в ім'я розваги, будьте чесні та вкажіть, що ви використовували, щоб отримати свій бал. Або використовуйте ideone, або використовуйте саму ванільну збірку (усі за замовчуванням) gcc 4.9.2. Конкурс покликаний довести до відома жахливість повідомлень про помилки C ++.


Коментарі не для розширеного обговорення; ця розмова переміщена до чату . Крім того, для обговорення того, що слід чи не слід вважати дублікатом, будь ласка, переведіть дискусію на мета .
Мартін Ендер

Три проблеми з використанням ideone для перевірки: Це примушує ім'я вихідного файлу до "prog.cpp", воно скорочує вихід помилок компілятора до 64 КБ і посилається, додаючи додаткові помилки. Тож це не буде хорошим інструментом перевірки.
Джейсон C

Я використовував GCC 4.9.2 з тестування інструментів Ubuntu repo.
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
@Dennis О, людина. Я отримав це. Дивіться цю другу редакцію. Ваш коментар був блаженним маскуванням.
Джейсон C

1
@JasonC Я не можу підтвердити це достатньо разів.
isaacg

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

3
@Dennis Whoa, приємно! Я буду залишати відповідь такою, - як я не думав додавати секунди #includeсамостійно. Що стосується нескінченності ... якщо вона все ще працює, коли я прокидаюсь завтра вранці, для мене це нескінченно достатньо. Буде тримати вас у курсі, га (хоча в даний час трубопровід становить 5,1 МБ / сек wc, тож якщо ви wcвикористовуєте 32-бітний лічильник, за моїми підрахунками, щось дивне може трапитися приблизно за 13 хвилин.)
Джейсон С

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 рівнів, тому ваш рекурсивний #includeефект ефективно стає 200-бітовим бінарним лічильником.
Ільмарі Каронен

3
Просто додайте більше включення рядків, щоб отримати нескінченний бал. Розмір виходу зростає швидше, ніж код.
jimmy23013

Це могло б однаково базуватися на одній з відповідей з попереднього питання .
Пітер Тейлор

2
Він зробив закінчити сьогодні вранці, з яким - то величезною кількістю , яке почалося з 8, і я випадково закрив вікно перед копіюванням номера , тому що я дивний. Я запускаю його знову.
Джейсон C

3
@JasonC Я також запустив це і отримав вихід 77,877,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)
        ^

[SNIP]

/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 не називає тип". Або %;створити "очікуваний некваліфікований ідентифікатор перед позначкою%".
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;

Безголівки:

#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
Вся ідейна річ - всілякі тупі.
Джейсон C

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

1

C, названий як .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

Я думаю, що це занадто близько до відповіді Стефана М.; Я б написав це як рекомендоване вдосконалення для цього рішення. Незважаючи на це, допускаються повторювані відповіді. Будь ласка, покладіть тут оригінал і згадайте будь-які натхнення (хоча можливо, ви придумали і це самостійно)
HyperNeutrino

1

Оцінка 12.xx (помилка ВИДАЛЕННЯ символу)

Вибачте, будь ласка, порушення правила 2 (додавання ІМХО АБО видалення одного символу було б у дусі правила), але це сталося зі мною випадково (таким чином, не використовуючи жодних "навмисно" образливих хитрощів) під час написання Реального коду (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.