Краткое содержание
Этот урок завершает восьмой раздел и вместе с ним курс. Он собирает то, чего достигли три урока раздела; восстанавливает цепочку понятий, ведущую от интерфейса модуля к отладке как методу; отделяет то, что из этого верно для любого языка, от того, что свойственно C++; показывает нарушение правила одного определения, которое никто не диагностирует, и сводит в один список всё неопределённое поведение курса вместе с тем, что обнаруживает каждый случай; повторяет в итоговой проверке навыки входной; предлагает шесть задач повышенной трудности, объединяющих раздел; и заканчивается итоговым проектом курса, точно специфицированным, с критериями оценивания, в четыре этапа, каждый с проверенным эталонным решением.
Цели обучения
- Организовывать программу в виде нескольких модулей с заголовочными файлами, защитой от повторного включения и контрактами, компилировать её раздельно и диагностировать сообщения компоновщика.
- Тестировать модуль, исходя из его спецификации, программой автоматических тестов, запускаемой под санитайзерами, и контролировать утверждениями то, что не может произойти.
- Находить ошибку методически (воспроизвести, сократить, сформулировать гипотезы, применить бисекцию) и с помощью отладчика, документируя расследование.
- Распознавать неопределённое поведение, показанное в курсе, вместе с тем, что обнаруживает каждый случай, и нарушение правила одного определения, которое никто не диагностирует.
- Объединять весь курс в проекте: специфицировать, декомпозировать, строить, тестировать, оценивать сложность и отлаживать программу управления табличными данными.
Чего достиг раздел
Раздел ставил целью научить организовывать, проверять на корректность и отлаживать программы, которые уже не помещаются ни в один файл, ни в голову. Цель достигнута с опорой на то, что введение объявило известным: объявление и определение, компиляцию и компоновку, контракт, инвариант и двоичный поиск. Программа каталога книг, которой открылся раздел, помещавшаяся в одном файле, ещё раз копировала parseInt и молча пропускала «Сто лет одиночества», потому что писала < там, где спецификация говорила «обе границы включительно»; в последнем параграфе этого урока она переписана как итоговый проект: четыре модуля с контрактами, главная программа, отвечающая на команды, и программа тестов с двадцатью пятью случаями. Два из этих случаев, «между, границы» и «между, один год», не проходят с условием исходной программы, и поэтому ошибка не могла бы вернуться незамеченной.
Несколько файлов и собственные библиотеки
Урок Несколько файлов и собственные библиотеки разделил программу на заголовочный файл, который объявляет, файл реализации, который определяет, и main.cpp, который использует. Он представил защиту от повторного включения, не допускающую двойного включения внутри одной единицы трансляции; правило одного определения, которое объясняет «multiple definition» и «undefined reference» и придаёт inline его нынешний смысл разрешения; раздельную компиляцию с -c, которая перекомпилирует только те объектные файлы, чьи исходники или заголовочные файлы изменились; и собственную библиотеку с функциями из уже пройденных уроков.
Тестирование
Урок Тестирование программ научил выводить случаи из спецификации, по областям, границам и особым случаям, с ожидаемым результатом, вычисленным другим путём; писать программу автоматических тестов, которая сообщает только о провалах и завершается с кодом 0 или 1; применять assert к тому, что не может произойти, зная, что -DNDEBUG стирает его вместе с условием; тестировать во время компиляции с помощью static_assert и constexpr; и запускать тесты с санитайзерами (санитайзером ошибок памяти AddressSanitizer и санитайзером неопределённого поведения UndefinedBehaviorSanitizer). Всё опирается на предостережение Дейкстры: тест показывает присутствие ошибок, но никогда не их отсутствие.
Отладка
Урок Отладка программ представил отладку как экспериментальный метод: воспроизвести сбой, сформулировать фальсифицируемые гипотезы, выбрать между ними с помощью экспериментов и применить бисекцию к подозрительному отрезку. Он разобрал инструмент (-g без оптимизации, настройку Visual Studio Code в трёх системах, реальный сеанс GDB, простые и условные точки останова, шаги и стек вызовов) и стратегии, которые ценнее самого инструмента: сократить случай, искать последнюю корректную точку с помощью утверждений и начинать с первого собственного кадра в отчёте санитайзера.
Загрузка содержимого…