简介: 在Java中,如果你不捕捉异常,你的代码甚至不进行编译,并在未处理的异常编译器崩溃。C++/GCC:如何检测未处理的异常在编译时
问: 有没有办法告诉GCC是“严”与Java在这种情况下,要加一个错误,或者至少在未处理的异常警告?
如果不是 - 是否有集成开发环境(对于Unix,请),可以凸显这种情况下,作为一个警告?
简介: 在Java中,如果你不捕捉异常,你的代码甚至不进行编译,并在未处理的异常编译器崩溃。C++/GCC:如何检测未处理的异常在编译时
问: 有没有办法告诉GCC是“严”与Java在这种情况下,要加一个错误,或者至少在未处理的异常警告?
如果不是 - 是否有集成开发环境(对于Unix,请),可以凸显这种情况下,作为一个警告?
你可以把一个C的唯一保证++的功能是它永远不会抛出异常都:
void f() noexcept;
然而,这在运行时将终止该程序时,会抛出异常。它在编译时没有被验证。
如果你想保证一个错误的处理,就可以得到返回了一个成员函数,它接受两个回调包装boost::variant<OK, Error>
一个类型的值最接近:为OK
情况下的回调,一个用于Error
案件。
我想抛出异常并处理它们,因为它提供了丰富的调试消息,所以'noexcept'不适合我。 {ok,error}结构体是我在'Perl'中常用的一种解决方案,但我认为在C++中我将能够有效地使用异常机制..如果我没有选择,我可以使用这个解决方案 – SomethingSomething 2014-09-29 07:53:44
在C++中是不可能的。异常规范是一个函数声明但不是它类型的部件的一部分。任何间接调用(通过指针或虚拟调用)都会完全清除有关异常的任何信息。
异常规范在C++ 11赞成noexcept
反正弃用,因此,这是不可能的编译器会不怕麻烦来加强这方面的语言功能。
哪个特征被描述在C++ 11中? – SomethingSomething 2014-09-29 08:00:42
[异常规范](http://en.cppreference.com/w/cpp/language/except_spec)支持'noexcept',@ user3322273。 – Mat 2014-09-29 08:06:53
你可以随时使用:
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(请参阅“例外”标题)。
首先,你的关于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.OutOfMemoryError
从java.lang.VirtualMachineError
派生 。虽然不容易,而不是 总是适用的,我已经写C++代码,成功 恢复从std::bad_alloc
。)
由于任何函数可以在没有正式规范的情况下抛出异常,这是不可能的。请记住,“崩溃”(像分段错误)不是可以用C++'catch'语句捕获的异常,它们也可以发生在任何地方。 – 2014-09-29 07:39:24
我同意分段错误。我只是想避免抛出和处理异常的突然崩溃。我想知道所有可能引发异常并调用它们的调用 – SomethingSomething 2014-09-29 07:50:03
未处理异常的默认行为是调用std :: terminate。自定义处理程序可以使用['std :: set_terminate'](http://en.cppreference.com/w/cpp/error/set_terminate)来安装。它可能无法解决您的紧急问题,但它可以让您的应用程序最后一次“注视”未知的异常。 – Niall 2014-09-29 07:55:33