3.2 – Процесс отладки

Добавлено 16 апреля 2021 в 21:10

Допустим, вы написали программу, и она работает некорректно – весь код компилируется нормально, но при запуске вы получаете неверный результат. Где-то вы допустили семантическую ошибку. Как ее найти? Если вы следовали лучшим практикам, написали небольшой фрагмент кода, а затем протестировали его, у вас может быть представление о том, где находится ваша ошибка. Или вы можете вообще не догадываться.

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

Поскольку мы еще не рассмотрели очень много тем о C++, наши примеры программ в этой главе будут довольно простыми. Из-за этого некоторые из показываемых здесь приемов могут показаться чрезмерными. Однако имейте в виду, что эти методы предназначены для использования с более крупными и сложными программами и будут более полезны в тех условиях (там, где они вам нужны больше всего).

Общий подход к отладке

После выявления проблемы ее отладка обычно состоит из пяти шагов:

  1. найдите основную причину проблемы (обычно это неработающая строка кода);
  2. убедитесь, что вы понимаете, почему возникает проблема;
  3. определите, как вы решите проблему;
  4. устраните проблему, вызвавшую неисправность;
  5. повторите тест, чтобы убедиться, что проблема устранена и не возникло никаких новых проблем.

Давайте воспользуемся аналогией из реальной жизни. Допустим, однажды вечером вы идете взять лед из автомата для льда в морозильной камере. Вы подносите чашку к дозатору, нажимаете, и… ничего не выходит. Ой. Вы обнаружили какой-то дефект. Чтобы вы сделали? Вы, вероятно, начнете расследование, чтобы выяснить, сможете ли вы определить основную причину проблемы.

Найдите первопричину: поскольку вы слышите, как дозатор льда пытается подать лед, вероятно, это не сам механизм подачи льда. Итак, вы открываете морозильную камеру и исследуете лоток для льда. Никакого льда. Это основная причина проблемы? Нет, это еще один симптом. После дальнейшего осмотра вы определяете, что льдогенератор не производит лед. Проблема в льдогенераторе или в чем-то другом? Морозильник всё еще холодный, водопровод не забит, и всё остальное вроде работает, поэтому вы делаете вывод, что основная причина в том, что льдогенератор не работает.

Разберитесь в проблеме: в данном случае это просто. Ледогенератор не делает лед.

Определите способ исправления. На этом этапе у вас есть несколько вариантов исправления. Вы можете обойти проблему (купить в магазине пакеты со льдом). Вы можете попытаться провести дальнейшую диагностику льдогенератора, чтобы увидеть, есть ли деталь, которую можно отремонтировать. Вы можете купить новый льдогенератор и установить его вместо нынешнего. Или вы можете купить новую морозильную камеру. Вы решили купить новый льдогенератор.

Устраните проблему: как только льдогенератор доставлен, вы устанавливаете его.

Повторное тестирование: после повторной подачи электропитания и ожидания в течение ночи ваш новый льдогенератор начинает делать лед. Новых проблем не обнаружено.

Теперь давайте применим этот процесс к нашей простой программе из предыдущего урока:

#include <iostream>
 
// Сложит два числа
int add(int x, int y)
{
    return x - y; // функция должна складывать, но это не так
}
 
int main()
{
    std::cout << add(5, 3) << '\n'; // должен выдать 8, но выдаст 2
    return 0;
}

Этот код хорош в одном: ошибка очень очевидна, потому что неправильный ответ выводится на экран в строке 11. Это дает нам отправную точку для нашего исследования.

Найдите основную причину: в строке 11 мы видим, что мы передаем литералы в качестве аргументов (5 и 3), поэтому здесь нет места для ошибки. Поскольку входные данные для функции add правильные, а выходные данные – нет, совершенно очевидно, что неправильное значение должна давать функция add. Единственная инструкция в функции add – это инструкция return, которая и должна быть виновником. Мы нашли проблемную строку. Теперь, когда мы знаем, на чем сосредоточить наше внимание, вы, вероятно, заметите, что мы вычитаем, а не складываем.

Разберитесь в проблеме: в этом случае очевидно, почему генерируется неправильное значение – мы используем неправильный оператор.

Определите способ исправления: мы просто заменим operator- на operator+.

Устраните проблему: это фактически замена operator- на operator+ и перекомпиляция программы.

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

Этот пример тривиален, но он иллюстрирует основной процесс, который вы пройдете при диагностике любой программы.

Теги

C++ / CppDebugLearnCppДля начинающихОбучениеОтладкаПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.