Visual Studio - исправление различного поведения в оптимизированной сборке - PullRequest
1 голос
/ 31 мая 2011

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

Чтобы проверить свои выводы, я сделал копию параметров сборки режима выпуска, но отключил оптимизацию (убедившись, что DEBUG и другие связанные параметры препроцессора были удалены), и он работал правильно. Что-то в процессе оптимизации изменяет поведение моей системы. Это, вероятно, потому, что есть переменные, которые я не инициализирую в своих классах где-то.

У меня вопрос: есть ли альтернатива, кроме ручной обработки моего кода, для обеспечения правильной инициализации? Я проверил всплывающие предупреждения, но все они связаны с преобразованием int в float / float в int и возможной потерей данных и квалификаторов enum, и ни одно из них не имеет отношения к альфе на моем спрайте.

Я использую Visual Studio 2010, если это имеет значение.

Ответы [ 3 ]

3 голосов
/ 31 мая 2011

Этот тип вещей может быть очень сложным для отладки.Я предлагаю вам заменить оптимизацию по очереди, пока не найдете ту, которая вызывает аномалию.Затем можно еще больше сузить проблему, применив эту оптимизацию к каждой единице (файлу) перевода один за другим.

Другой способ решения этой проблемы - это, по сути, трассировка данных.Проанализируйте код, чтобы определить, какой элемент данных контролирует вашу альфа.Найдите каждый оператор, который пишет в данные.Поместите точку останова или следы на эти заявления.Затем определите первую точку в исполняемом файле, где данные о выпуске отличаются от данных отладки.

1 голос
/ 31 мая 2011

Включите как можно больше предупреждений, чтобы перехватывать неинициализированные переменные. Запустите код через статический инструмент LINT, например, cppcheck. Прошло много времени с тех пор, как я использовал VS, но я уверен, что вы можете настроить свой отладчик так, чтобы он прерывал доступ к неинициализированным обращениям к переменным и отслеживал его оттуда.

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

0 голосов
/ 31 мая 2011

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

template<typename T> class always_initialized {
    T t;
public:
    operator T&() { return t; }
    operator const T&() const { return t; }
    always_initialized() : t(T()) {}
    template<typename K> always_initialized(K&& ref) : t(std::forward<K>(ref)) {}
};
...