Привет!
Я рад сообщить, что два раунда Codeforces прошли вполне хорошо в плане работы Codeforces, чему я очень рад. Эти дни ночи я провел в профайлере, фиксах кода, изучению настроек MariaDB.
Кроме этого мне удалось выделить несколько часов в воскресенье (если честно, то до утра понедельника), чтобы закончить давно планируемое нововведение.
Встречайте, диагностика решений на С++!
Постоянные посетители Codeforces уже устали от вопросов менее опытных участников: «Почему моё решение не работает на тесте на серверах Codeforces, если локально я его запускаю, и оно работает? У вас неправильный компилятор/серверы!» В 99% случаях это пример неопределённого поведения в программе. Иначе говоря, программа содержит ошибки, которые в силу ряда обстоятельств не воспроизводятся при локальном запуске, но воспроизводятся при запуске на серверах Codeforces.
Иногда, это непросто заметить подобную ошибку. Небольшой выход за границу массива может приводить и к неправильному ответу на тесте и к ошибке выполнения программы.
В g++/clang++ есть замечательная штука sanitizers (переводится как «дезинфицирующее средство»). Это такие способы скомпилировать программу в особом режиме так, что при своей работе она будет проверять свой ход выполнения на неопределенное поведение (и некоторые другие ошибки) и в случае возникновения выдавать их в stderr. Похожей функциональностью обладает и drmemory (некоторый аналог valgrind, но для Windows), который для определения ошибок запускает программу в особом режиме. При таких диагностических запусках колоссально страдает производительность выполнения программы (программа выполняется медленнее в 5-100 раз и требует больше памяти), но зачастую оно того стоит.
Теперь автоматическая диагностика в некоторых случаях предотвратит вопрос вида «Почему не работает???», указав на ошибку или её вид!
Если ваше решение:
- написано на C++,
- упало с вердиктом «неправильный ответ» или «ошибка исполнения»,
- на этом тесте отработало предельно быстро и съело мало памяти,
то оно будет перезапущено, используя специальные диагностические компиляторы (clang++ c sanitizers и g++ с drmemory). Если при таком запуске произойдет ошибка исполнения, то журнал запуска будет отображен в деталях тестирования в разделе «диагностика». Конечно, эта запись будет содержать технический лог на английском языке, но зачастую он укажет вам на ошибку программы. Часто он содержит причину падения программы и даже строку исполнения. Если диагностика не отображается, значит хотя бы одно условие выше не выполнилось или диагностика не обнаружила ошибок.
Пример отображения диагностики: здесь написано, что произошел выход за границу массива в 78 строке.
Таким образом, диагностика будет иногда помогать найти вам ошибку вида "выход за границу массива", "знаковое переполнение", "неинициализированная переменная на стеке" и т.п. Внимательно читайте диагностику и не допускайте подобных ошибок в будущем!
Желаю, чтобы ваши программы не падали. Надеюсь, нововведение будет полезно!
Есть большие планы как полезно применять такую диагностику. Не уходите далеко, ждите новостей, скоро будут еще нововведения!
P.S. Так же диагностические компиляторы просто доступны для использования. Например, их можно использовать на вкладке «Запуск». Напоминаю, что программа работает многократно медленнее и потребляет больше памяти в режиме диагностики.