Написать короткую программу, которая будет генерировать максимально возможное сообщение об ошибке, в стандартном компиляторе C ++ ( gcc
, cl.exe
, icc
или clang
).
Оценка каждой записи - это количество символов в самом длинном сообщении об ошибке, выданном компилятором. Типы, включенные в ваш исходный код и цитируемые компилятором, считаются одним символом.
Мошенничество
Вы всегда можете переопределить шаблон в шаблоне в шаблоне с длинными именами, но я ожидаю чего-то креативного. Я пытался предотвратить это по последнему правилу, но, конечно, правила могут быть лучше, и я буду рад улучшениям.
code-challenge
c++
error-message
Элазар Лейбович
источник
источник
Error.message.length / code.length
.Ответы:
Шаблон сообщения об ошибках весело расшифровывать. Учти это:
Компиляция с
gcc -c error.cpp
(4.6.3) выдаст 15786 байт с самой длинной строкой из 330 символов.Редактировать 2016-04-29: gcc 5.3.0 стал немного лучше: всего 9300 байт, самая длинная строка длиной 361 символ ...
Изменить 2019-04-04: gcc 6.5.0: 11237 байт, но дает некоторые подсказки об ошибке, как в следующих строках:
источник
19 символов
Создайте файл
a.cpp
с таким содержанием:Компилировать как:
и получите удивительные сообщения об ошибках 21300 строк :
...
... 21280 строк ошибок ...
...
источник
#include __FILE__
очень длинного имени файла?clang++ -ferrorlimit=1000 a.cpp
. Самая длинная строка длиной 466 символов.98 (обязательно) символов:
Создает следующий вывод ошибок в GCC (4.4.5):
Статистика:
Ungolfed (производит более длинную продукцию):
Я обнаружил это, когда хотел посмотреть, поддерживает ли C ++ полиморфную рекурсию (и, как вы можете ясно видеть, это не так). Вот тривиальный пример полиморфной рекурсии в Haskell:
Здесь, это требует Haskell действовать , как он конкретизирует
Show x
,Show [x]
,Show [[x]]
,Show [[[x]]]
, до бесконечности. Haskell делает это путем превращения(Show x) =>
в неявный параметр функции,f
добавленной компилятором, что-то вроде этого:C ++ делает это, буквально пытаясь создать такие экземпляры, пока глубина экземпляра шаблона не будет превышена.
источник
cl
не любит неявныйint
в режиме C ++), он генерирует 14,380,923 байт вывода ошибок после 4½ минут процессорного времени и пика использования памяти около 100 МБ.Основываясь на соотношении длина сообщения / длина кода, это может быть лучшим решением:
Сообщение (81):
81/0 = Инф
источник
279 символов
С gcc 4.2.1 генерирует ошибку
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘foofoo....foofoo’
с 2 ^ 21 копиямиfoo
. 6,291,558 байт всего. Это примерно как большой идентификатор , как я могу получить, заменивfoo
сfood
генерирует ICE.источник
#define A(s) s##s##s##s #define B(s) A(s) #define C(s) B(B(B(s))) #define D(s) C(C(C(s))) D(foo)
. Это приводит меня к сообщению об ошибке «длиннее» с гораздо меньшим количеством кода и растет намного быстрее с увеличением шаблона в любом измерении, поскольку мы, по сути, реализуем функцию Аккермана.Аналогично VJo:
a.cpp:
g ++ a.cpp
производит много вывода (по крайней мере 2 гигабайта, прежде чем я его убил)
источник
Следующий код основан на фактической ошибке, с которой я однажды столкнулся.
(используя gcc)
Довольно очевидная рекурсия шаблона, но так как я использовал
ftemplate-depth=100000
для этого запуска, это не выдает ошибку. Истинный источник сообщений об ошибках исходитchar baz[i];
, который выдает ошибку, когдаi
падает до -1.Примерно через полчаса я сижу на 21 000 ошибок компилятора , 300 000 строк сообщений об ошибках и 280 мегабайт оперативной памяти, используемой компилятором. И это не показывает никаких признаков остановки.
РЕДАКТИРОВАТЬ:
Час спустя, теперь на 36 000 ошибок компилятора , 504 000 строк сообщений об ошибках и 480 мегабайт ОЗУ ... и все еще продолжается.
РЕДАКТИРОВАТЬ № 2:
Примерно через полчаса:
Итоговая статистика: 38 876 ошибок компилятора , 544 624 строки сообщений об ошибках, общий объем данных 48,8 мегабайт , и 518,9 мегабайт оперативной памяти, использованной компилятором до его сбоя .
источник
28 байт
Саботаж стандартной библиотеки:
Используя clang на OS X 10.9:
456 строк ошибок, 50 ошибок и ошибка компилятора !
Clang версия:
источник
Я случайно наткнулся на это:
На c ++ x11 он выдает 44 КБ сообщений об ошибках, в которых компилятор пытается сказать: Пожалуйста, определите местозаполнитель для первого аргумента, если вы определите его для второго.
Посмотри на Ideone .
источник
C ++
На основе решения BЈовић:
Файл: golf.cpp:
Выполнение этого в G ++ не закончится, однако, я вычислил длину ошибки, которую он в конечном итоге испустит, примерно 85 * 2 ^ 140 терабайт.
источник
C ++ 11 вариационных шаблонов (69 символов)
Конфигурируя максимальную глубину создания шаблона, вы можете установить длину ошибки. Вот пример использования GCC 4.8.1 с глубиной шаблона по умолчанию (900):
Также вы можете добавить еще десять символов и использовать недопустимое целое число без знака, чтобы увеличить длину ошибки:
Вот пример работы на ideone.
источник
82 байта: этот работает аналогично подходу Джои Адамса , но сообщение об ошибке будет расти в геометрической прогрессии по отношению к
-ftemplate-depth
(потому чтоstd::set<T>
на самом делеstd::set<T, std::less<T>, std::allocator<T>>
).Так
(x = -ftemplate-depth) >= 28
, будет 1460 × 3 x-27 + 269x - 5381 байт сообщений об ошибках (скомпилировано gcc 7.2.0). То есть в настройках по умолчанию (x = 900) теоретически будет выдано около 4,9 × 10 419 байт сообщения об ошибке .Обратите внимание, что без
return
оператора сообщения об ошибках будут создаваться только в конце компиляции. (поэтому в настройках по умолчанию вы не получите сообщения - сначала вам не хватит памяти.)Предупреждение: компиляция этой программы будет занимать много памяти.
Попробуйте онлайн!
источник
map
кажется более злым, такstd::map<T,T>
какstd::map<T,T,std::less<T>,std::allocator<std::pair<T,T>>>
вы получаете 5-стороннюю рекурсию вместо 3, и только на 2 байта больше.-ftemplate-depth=13
, 423 572 байтов в-ftemplate-depth=14
и 1247 322 байтов в-ftemplate-depth=15
.map
вариант генерирует 13 373 990 байт на глубине 14 и 66 759 871 байт на глубине 15.-ftemplate-depth=1024
это где-то к северу от 10 ^ 713 байт сmap
вариантом. Я считаю, что это означает, что вы выиграли ...Это дает бесконечный вывод на GCC 5.2 и Clang 3.6 (на Clang требуется
-ferror-limit=0
, на GCC работает с настройками по умолчанию):источник
Файл с именем
a.cpp
. Код:Это вилочная бомба, где n = 40.
источник
=>
=>
компилировать с
index_sequence, кажется, обходит проблему ограничения глубины инстанцирования шаблона
ошибки выглядят так: вся последовательность цифр 0 ... C-1 выглядит так, как будто она напечатана 4 * C раза
и числовые последовательности могут превышать установленный по умолчанию предел глубины создания шаблона, конечно, потому что он встроен:
источник