Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье объясняется, какие параметры компилятора следует задать, чтобы вы могли лучше отлаживать оптимизированный код.
Лучший интерфейс доступен начиная с Visual Studio 2022 версии 17.14, который позволяет отлаживать оптимизированный код, как если бы он был скомпилирован неоптимизирован, сохраняя скорость оптимизированного кода. Дополнительные сведения см. в динамической отладке C++ (предварительная версия).
Примечание.
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от ваших текущих параметров или используемой редакции. Чтобы изменить параметры, выберите "Импорт и экспорт параметров" в меню "Инструменты". Дополнительные сведения см. в разделе Сброс всех параметров.
Примечание.
Параметр компилятора /Zo (улучшенная отладка для оптимизированного кода), появившийся в Visual Studio Update 3, создаёт более подробные сведения об отладке для оптимизированного кода проектов, которые не созданы с параметром компилятора /Od. Смотрите /O Опции (Оптимизация кода). Это включает улучшенную поддержку отладки локальных переменных и встроенных функций.
Редактировать и Продолжить отключено при использовании параметра компилятора /Zo.
Когда компилятор оптимизирует код, он изменяет положение и реорганизует инструкции. Это приводит к более эффективному компилированному коду. Из-за этого изменения отладчик не всегда может определить исходный код, соответствующий набору инструкций.
Оптимизация может повлиять:
Оптимизатор может удалить локальные переменные или переместить их в расположения, которые отладчик не понимает.
Позиции внутри функции, которые изменяются при слиянии блоков кода оптимизатором.
Имена функций для кадров в стеке вызовов, возможно, будут неправильными, если оптимизатор объединяет две функции.
Кадры, которые отображаются в стеке вызовов, почти всегда верны, однако при условии, что у вас есть символы для всех кадров. Кадры в стеке вызовов будут неправильными, если произошло повреждение стека, если у вас есть функции, написанные на языке ассемблера, или если в стеке вызовов есть кадры операционной системы без соответствующих символов.
Глобальные и статические переменные всегда отображаются правильно. Также и структура макета. Если у вас есть указатель на структуру и значение указателя правильно, каждая переменная члена структуры будет отображать правильное значение.
Из-за этих ограничений следует выполнять отладку с помощью неоптимизированной версии программы, если это возможно. По умолчанию оптимизация отключена в конфигурации Debug программы C++, и включена в конфигурации Release.
Однако ошибка может отображаться только в оптимизированной версии программы. В этом случае необходимо выполнить отладку оптимизированного кода.
Включение оптимизации в конфигурации отладочной сборки
При создании проекта выберите целевой объект
Win32 Debug
. Используйте целевой объектWin32 Debug
до полной отладки программы, и вы будете готовы создать целевой объектWin32 Release
. Компилятор не оптимизирует целевой объектWin32 Debug
.Выберите проект в обозревателе решений.
В меню Представления щелкните Страницы Свойств.
В диалоговом окне страниц свойств убедитесь, что
Debug
выбран в раскрывающемся списке конфигурации.В представлении папок слева выберите папку C/C++.
В папке C++ выберите
Optimization
.В списке свойств справа найдите
Optimization
. Настройка рядом с ним, вероятно, указана какDisabled (
/Od)
. Выберите один из других вариантов (Minimum Size``(
/O1)
,Maximum Speed``(
/O2)
,Full Optimization``(
/Ox)
илиCustom
).Если выбран параметр
Custom
дляOptimization
, теперь можно задать параметры для любого из других свойств, отображаемых в списке свойств.Выберите узел "Свойства конфигурации", C/C++, узел "Командная строка" на странице свойств проекта и добавьте
(
/Zo)
в текстовое поле "Дополнительные параметры".При отладке оптимизированного кода используйте окно disassembly, чтобы узнать, какие инструкции создаются и выполняются. При установке точек останова необходимо знать, что точка останова может перемещаться вместе с инструкцией. Например, рассмотрим следующий код:
for (x=0; x<10; x++)
Предположим, что вы устанавливаете точку останова в этой строке. Вы можете ожидать, что точка останова будет достигнута 10 раз, но если код оптимизирован, точка останова достигается только один раз. Это связано с тем, что первая инструкция задает x
значение 0. Компилятор распознает, что это нужно сделать только один раз и перемещает его из цикла. Точка останова перемещается вместе с ней. Инструкции, которые сравнивают и увеличивают x
, остаются внутри цикла. При просмотре окна дизассемблирования единица шага автоматически устанавливается на инструкцию для большего контроля, что полезно при пошаговом переходе по оптимизированному коду.