Сообщения Об Ошибках + Шаблоны: Несколько Простых Советов



Немного лирики Должен сразу предупредить, что данная тема вряд ли будет полезна программистам, давно и прочно дружящим с C++.

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

Как показывает практика, зачастую все не так страшно, как кажется и вполне помогает понять, в чем проблема.

Идея написать такую заметку возникла в процессе написания программы, активно использующей Boost::Spirit2 — сложная грамматика, обилие семантических действий, создание AST через значение атрибута и тому подобные радости.

В какой-то момент я заметил, что на исправление многих ошибок у меня уходит всего одна-две минуты, тогда как в начале работы над проектом в подобных случаях анализ ситуации мог занять до часа.

Все написано исходя из работы с gcc, но думаю не составит труда провести аналогию с используемым %compiler_name&.

Пришло время поделиться!



Что нам поможет?

  • Фатальные ошибки Прежде всего, вам следует включить опцию компилятора, которая делает любую ошибку фатальной.

    Когда GCC Этот -Wfatal-ошибки .

    В случае с метапрограммированием изучение более одного сообщения об ошибке одновременно пока не имеет особого смысла — скорее всего, исправление первого повлияет на множество последующих.

    И стена текста станет гораздо ниже.

  • Посмотрите в корень Если вы присмотритесь, то обнаружите, что сообщения об ошибках шаблона имеют примерно такую структуру:

    In file included from %header path%, from %header path%, .

    from %source filename%: %header path%: In function '%full name%' %header path%: instantiated from '%full name%' .

    %source filename%: instantiated from %full name% .

    %header path%: error: %error description%

    А если присмотреться еще внимательнее, то окажется, что блок с «instantiated from», проходящий через всю иерархию включенных заголовочных файлов, является самым большим и бесполезным.

    Вряд ли нас часто интересует, какими обходными путями дело дошло от вызова библиотечной функции до ошибки.

    Но меня интересует, что это за ошибка и какая строка нашего кода (блок «instanceated from» для %source filename%) ее сгенерировала.

    А это совсем немного и вполне читабельно.

    Иногда достаточно просто посмотреть на строчку в коде, из-за которой всё пошло не так, и сразу видишь глупейшую опечатку, вылившуюся в такую нецензурную лексику.

    Вам даже не придется читать сообщение об ошибке, которое в такой ситуации все равно ничего значимого не скажет.

  • typedef — это typedef Удобно иметь под рукой набор правил поиска и замены для основных определений типов, используемых в проблемном коде.

    Даже короткий std::basic_string в форме выглядит намного лучше станд::строка , не говоря уже о векторах списков пар векторов и очередей.

    Например, в vim можно написать простой скрипт замены, с помощью которого можно каждый раз запускать сообщение об ошибке, если оно длиннее пары строк, и делать его читабельным.

  • Чтение источников Если в коде шаблона есть ошибка, то мы находимся почти в одном шаге от исходного кода.

    Когда вы уже не имеете ни малейшего представления, в чем может быть проблема, стоит открыть ту часть заголовочного файла библиотеки, на которую жалуется компилятор (%header path%: error: ) и присмотреться.

    Как правило, даже в очень брутальных буст-библиотеках небольшие кусочки индивидуально читаются и понятны.

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

Я желаю тебе того же.

Какие трюки вы используете? Буду рад прочитать советы по теме в комментариях.

Я предлагаю коллективно бороться с недостатками проектирования на C++.

Теги: #C++ #отладка #GCC #сообщения об ошибках #шаблоны #Chulan

Вместе с данным постом часто просматривают: