2015-04-16 3 views
1

Я нашел странное поведение в VisualStudio (2008 and 2013).VisualStudio debug продолжает необработанное исключение

Давайте начнет с testcode:

#include <string> 
#include <fstream> 
#include <iostream> 
using namespace std; 

string readFile() 
{ 
    std::fstream f; 
    f.open("not_good_file.txt", std::fstream::in); 

    if (!f.good()) 
     throw std::exception("unable to read file"); 

    f.seekg(0, f.end); 
    std::streamoff len = f.tellg(); 
    f.seekg(0, f.beg); 

    string result(len, '\0'); 
    f.read(&result[0], len); 
    f.close(); 
    return result; 
} 

int main(int argc, char** argv) 
{ 
    cout << "before exception" << endl; 
    readFile(); 
    cout << "after exception" << endl; 
    return 0; 
} 

При работе без отладчика приложения Прерывает, как ожидался, но когда я достигну незащищенного исключение при отладке, известное окно сообщений отображает, чтобы сказать мне о неперехваченном исключении. Я получаю опцию break, где показана строка, в которой было выбрано исключение (если доступно), и опция continue, которая (как указано в названии) продолжает приложение.

В результате получается, что код непосредственно после исключения выполнен, что означает, что f.tellg() возвращает -1, длина которого не действительна для std::string.

Почему это происходит?

+0

Что вы ожидали в противном случае? Вы просите приложение продолжить, и оно продолжается? Также в производственном коде вы, вероятно, должны проверять, является ли 'len' положительным в любом случае, прежде чем неявно лить его в целое число без знака. – stijn

+0

Я бы предположил, что сообщение появляется только как напоминание, и при использовании 'continue' он будет делать то, что он будет делать без отладчика (в этом случае прервать) – Zaiborg

ответ

1

В результате получается, что этот код непосредственно после выполнения исключения означает, что f.tellg() возвращает -1, для которого не допустима длина для std :: string.

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

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

После того, как IDE предоставит вам возможность «продолжить», а это означает, что «вызов std :: terminate» является гайкой (потому что тогда «продолжить» означает «остановка»). Таким образом, в этом случае «continue» означает «продолжить выполнение, как если бы исключение не было», а не «продолжить выполнение для завершения приложения».

+0

спасибо за разъяснение. не знал, что 'continue' означает' ignore exception'. – Zaiborg

Смежные вопросы