Немного лирики Должен сразу предупредить, что данная тема вряд ли будет полезна программистам, давно и прочно дружящим с 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
-
Ошибка 2010
19 Oct, 24 -
Rackspace Намного Превосходит Amazon Ec2
19 Oct, 24 -
Синтез 3D-Звука :: Кланк
19 Oct, 24 -
Как Еще Это Возможно?
19 Oct, 24