2015-04-16 37 views
1

我在VisualStudio (2008 and 2013)中发现了一个奇怪的行为。VisualStudio调试继续未处理的异常

让我们先从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无效的长度。

调试器为您提供了运行的选项,就好像异常不存在(继续)或在异常站点中断(中断)一样。

正常情况下,当您选择继续时,应用程序应该跳到catch块的异常(或者将unwindingm和然后堆栈到catch块)。尽管你没有catch块,所以应用程序应该跳到std::terminate(并结束执行)。

让IDE有“继续”的选项,而“call std :: terminate”的意思是坚果(因为“继续”实际上意味着“停止”)。因此,在这种情况下,“继续”意味着“继续执行,如果异常不在那里”,而不是“继续执行以终止应用程序”。

+0

谢谢澄清。不知道“继续”意味着“忽略异常”。 – Zaiborg