Исключение С++ "Пропускает" предложение Try-Catch в MSVC x64
Я пишу программу на С++. Программа отлично работает для Win32 (x86), и недавно я попытался собрать ее изначально для x64. Конечно, материал сразу не работал.
После отладки проблемы мне удалось воспроизвести ее с помощью этого простого фрагмента кода:
class MyException { };
int main()
{
try {
for (;;) {
try {
std::cout << "Throwing" << std::endl;
throw MyException();
if (1 == 0) {
continue;
}
} catch (const MyException&) {
std::cout << "Catch 1" << std::endl;
}
}
} catch (const MyException&) {
std::cout << "Catch 2" << std::endl;
}
std::cout << "Done" << std::endl;
return 0;
}
(я скоро объясню предложение if (1==0)
)
При компиляции этого кода с использованием MSVC для x86 (я использовал 2010) результат будет таким, как ожидалось:
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
...
И так далее, в бесконечном цикле.
Однако компиляция этого кода для x64 приводит к:
Throwing
Catch 2
Done
Исключение полностью пропускает предложение внутреннего catch!
Это происходит только тогда, когда в моем коде существует предложение if (1 ==0)
. Когда я удаляю его, исключение попадает в "Catch 1", как ожидалось.
Я пробовал использовать другие компиляторы:
- Эта ошибка также возникает в VS 2012.
- MinGW и MinGW-w64 работают должным образом.
Мой вопрос: это ошибка MSVC, или это какое-то поведение undefined в С++, которое мне не хватает?
Если это действительно ошибка MSVC, я хотел бы услышать некоторое понимание причины.
Спасибо.
Ответы
Ответ 1
Эта ошибка может иметь какое-то отношение к оптимизации компилятора - интересно, что компоновщик выйдет из строя в вашей версии сборки (когда теоретически будет включена полная оптимизация).
У вашей отладочной сборки оптимизация полностью отключена (/Od)?
Справка Visual Studio также содержит инструкцию (в разделе "Оптимизация наилучшей практики" ), препятствующая блоки try/catch в 64-битном коде.
Если вы отключите оптимизацию в сборке релизов, компоновщик не сработает. Он также не будет разбиваться (но будет воспроизводить плохое поведение), если вы удалите только инструкцию "продолжить".
if (1==0) {
//continue;
}
Ответ 2
Попробуйте переключатель переключателя /FA:
http://msdn.microsoft.com/en-us/library/367y26c6%28v=vs.80%29.ASPX
где-нибудь в "дополнительном выходном файле" в ваших "настройках компилятора". (убедитесь, что все остальные настройки являются именами)
Затем сделайте разницу между обоими выходами. разместите здесь diff. Я уверен, что некоторые люди смогут рассказать вам, почему и как, и, возможно, некоторые настройки компилятора или обходные пути кода.
Ответ 3
Это старая известная проблема, после ее выкапывания это то, что мы узнали некоторое время назад.
http://social.msdn.microsoft.com/Forums/en-US/19eb8218-0dc4-4e4f-954f-4c4c3b3cd118/why-am-i-not-being-alerted-of-exceptions-from-methods-that-are-run-when-the-application-loads?forum=csharpide