#c #visual-studio-2010
#c #visual-studio-2010
Вопрос:
У меня есть проект C в Visual Studio 2010.
Я просто пытаюсь сравнить две строки друг с другом, но я вижу совершенно другое поведение в моей сборке Release. Отладочная сборка работает так, как ожидалось. Я не вносил никаких изменений в оптимизации, кроме значений по умолчанию, которые устанавливает Visual Studio 2010.
Вот мой код:
wchar_t validCRC[] = L"0xd07153b9";
wchar_t thisCRC[] = L"0xd07153b9"; // this is calculated on the fly but I get same behavior if I set it manually. i also tried setting these both to L"hello" and got same result
int cmp = 0;
cmp = wcscmp(validCRC, thisCRC); // if I put a breakpoint here, the visual studio debugger says 'cmp' is not in scope.
pLog->Write("value of cmp: %d", cmp); // in both DEBUG and RELEASE, this prints "value of cmp: 0"
if (cmp == 0)
{ // yet for some reason, the DEBUG build follows this path
return true;
}
else
{ // the RELEASE build follows this path
return false;
}
Комментарии:
1. Какое значение cmp, если не 0?
2. Это не настоящий код, не так ли? Опубликуйте что-нибудь минимальное, что воспроизводит вашу проблему.
3. Возможно ли, что вычисленный thisCRC не завершается с нулевым завершением?
4. @ Dabbler — я подтвердил, что значение cmp равно 0 в обеих сборках. @ K-ballo — я не совсем уверен, что вы ищете. Вы хотите использовать void main() вокруг него? @ ThierryFranzetti — но они оба устанавливаются одинаково, используя L»stringhere»
5. Тогда проблема связана с оптимизацией, выполняемой компилятором. В сборке release (т. Е. С оптимизацией) отладчик часто неправильно отображает значения переменных, и при пошаговом выполнении может показаться, что точка выполнения находится там, где ее на самом деле нет. Это связано с тем, что корреляция между строками исходного кода и сгенерированным машинным кодом гораздо менее прямая, чем в неоптимизированном коде.
Ответ №1:
Сборки Release оптимизированы, поэтому отладчику часто бывает сложно выдавать вам значения отдельных переменных, особенно локальных переменных, которые часто являются сохраненными регистрами, которые используются для чего-то еще несколькими инструкциями позже.
Вот почему вы используете отладочную сборку для отладки и сборку release для сборки, которую вы выпустите.
Если вам действительно нужно отладить проблему, которая возникает только в сборке release (очень часто причиной являются неинициализированные переменные), вы можете использовать специфичную для компилятора #pragma только для деоптимизации определенных частей, или вы можете деоптимизировать определенные файлы, или вы можете использовать инструкции printf.
РЕДАКТИРОВАТЬ: когда вы говорите «следовать» этому пути, вы, вероятно, имеете в виду, что так оно и выглядит, когда вы проходите через него в отладчике. Опять же, код оптимизирован, поэтому сборка не соответствует исходному коду. Возвраты, в частности, часто оптимизируются так, что в сборке есть только одна фактическая инструкция возврата. Таким образом, пошаговое выполнение кода в сборке release не является надежным способом определить, что происходит.
Еще раз, правильный способ отладки сборок release — использовать printfs и другие механизмы. Вы все равно можете использовать отладчик, чтобы получить общее представление о том, что происходит, но вы не можете полагаться на подобные детали.
Комментарии:
1. Использование printf подтверждает, что cmp равен 0 в обеих сборках
2. Точно! printf не лжет. Значения переменных, однако, выполняются (в сборках release). В некоторых средах в некоторых отладчиках вы можете видеть совершенно неправильные значения. Итак, еще раз, если вы хотите что-то отладить в отладчике, используйте сборку debug . Для сборки release вам понадобятся другие средства отладки, такие как printf.
3. Хорошо, я увидел ваше редактирование, поэтому отредактировал свой ответ. Опять же: отладчик в сборках release обязательно предоставит вам вводящую в заблуждение информацию. Результат — это то, что имеет значение.
Ответ №2:
Попробуйте напечатать значение вместо того, чтобы полагаться на отладчик в режиме Release. Оптимизатор очень агрессивен, и ваши символы могут указывать на код, который оптимизируется.
Комментарии:
1. Я сделал, и в обоих случаях значение cmp равно 0