2014-09-29 132 views
2

简介: 在Java中,如果你不捕捉异常,你的代码甚至不进行编译,并在未处理的异常编译器崩溃。C++/GCC:如何检测未处理的异常在编译时

问: 有没有办法告诉GCC是“严”与Java在这种情况下,要加一个错误,或者至少在未处理的异常警告?

如果不是 - 是否有集成开发环境(对于Unix,请),可以凸显这种情况下,作为一个警告?

+4

由于任何函数可以在没有正式规范的情况下抛出异常,这是不可能的。请记住,“崩溃”(像分段错误)不是可以用C++'catch'语句捕获的异常,它们也可以发生在任何地方。 – 2014-09-29 07:39:24

+0

我同意分段错误。我只是想避免抛出和处理异常的突然崩溃。我想知道所有可能引发异常并调用它们的调用 – SomethingSomething 2014-09-29 07:50:03

+1

未处理异常的默认行为是调用std :: terminate。自定义处理程序可以使用['std :: set_terminate'](http://en.cppreference.com/w/cpp/error/set_terminate)来安装。它可能无法解决您的紧急问题,但它可以让您的应用程序最后一次“注视”未知的异常。 – Niall 2014-09-29 07:55:33

回答

0

你可以把一个C的唯一保证++的功能是它永远不会抛出异常都:

void f() noexcept; 

然而,这在运行时将终止该程序时,会抛出异常。它在编译时没有被验证。

如果你想保证一个错误的处理,就可以得到返回了一个成员函数,它接受两个回调包装boost::variant<OK, Error>一个类型的值最接近:为OK情况下的回调,一个用于Error案件。

+0

我想抛出异常并处理它们,因为它提供了丰富的调试消息,所以'noexcept'不适合我。 {ok,error}结构体是我在'Perl'中常用的一种解决方案,但我认为在C++中我将能够有效地使用异常机制..如果我没有选择,我可以使用这个解决方案 – SomethingSomething 2014-09-29 07:53:44

2

在C++中是不可能的。异常规范是一个函数声明但不是它类型的部件的一部分。任何间接调用(通过指针或虚拟调用)都会完全清除有关异常的任何信息。

异常规范在C++ 11赞成noexcept反正弃用,因此,这是不可能的编译器会不怕麻烦来加强这方面的语言功能。

+0

哪个特征被描述在C++ 11中? – SomethingSomething 2014-09-29 08:00:42

+2

[异常规范](http://en.cppreference.com/w/cpp/language/except_spec)支持'noexcept',@ user3322273。 – Mat 2014-09-29 08:06:53

0

你可以随时使用:

int main() 
{ 
    try { 
     ... your usual main ... 
    } 
    catch(...) 
    { 
     std::cerr << "Unhandled exception caught" << std::endl; 
    } 
} 

然而,这是一个相当差的解决方案。

不幸的是,C++的性质使得它很难赶上那里的东西抛出一个异常的情况,它没有处理,因为几乎一切都已经抛出异常的潜力。我只能想到代码审查 - 也许代码分析工具,如围绕CLANG构建的代码分析工具将具有这样做的能力,但它可能不会100%准确。事实上,我甚至不确定Clang Analyzer是否完全理解throw/try/catch,因为它似乎没有发现一些相当基本的错误http://clang-analyzer.llvm.org/potential_checkers.html(请参阅“例外”标题)。

0

首先,你的关于Java的说法是错误的;只有特定的 类型的异常会阻止编译代码。而对于 ,大部分情况下,这些类型的例外都与 相对应,它们可以更好地由返回码处理。例外的是,通常只有 一个合适的解决方案,通过 传播错误了大量的功能时,你不希望有添加 异常规范所有的这些功能。

这真的是为什么Java使得它的不同之处:例外 从java.lang.Error派生平时应崩溃 (断言失败和类似于C++);并且 从java.lang.RuntimeException派生的例外应该是 C++中的例外。因为它不是 合理的让每个函数声明它可能会抛出 其中之一。

至于其他方面,您希望立即在调用代码中捕获 的例外情况,通常最好通过返回码处理 ,而不是例外; Java在这里可能会使用异常 ,因为它没有输出参数,这会使得使用 返回代码更加尴尬。当然,在C++中,你也可以用 静静地忽略返回码,这是一个缺点(但是 历史原因等)。但真正的问题是合约, 这远比函数f可能抛出/返回x更复杂; 它更符合“功能f 投掷/返回x, 如果条件c满足”。而且我知道没有任何语言有 强制执行的手段。在C++中(对于Java中的检查异常 ),异常规范更多地沿着 的行“函数f不会抛出任何东西,但x”。其中一般 不是很有用,除非“x”表示全部例外。为了 编写真正健壮的代码,您需要保证永远不会抛出的几个函数。有意思的是,你可以用这个 在C++中指定它,包括pre-C++ 11(throw())和 (noexcept);你不能用Java,因为你不能指定 函数不会抛出java.lang.RuntimeError

(或A java.lang.Error,但是这不是一个问题,因为如果 你得到其中的一个,你的应用程序反正大清洗。只是 你怎么有望从 java.lang.VirtualMachineError恢复?当然,你不能 真的希望能够从段违反 C++或者恢复虽然... java.lang.OutOfMemoryErrorjava.lang.VirtualMachineError派生 。虽然不容易,而不是 总是适用的,我已经写C++代码,成功 恢复从std::bad_alloc。)