例外与错误

Exceptions vs. errno

本文关键字:错误      更新时间:2023-10-16

作为一名C程序员,我对异常没有太多经验。我习惯于errno作为在多个函数调用之间传达错误的一种方式。话虽如此,我没有看到例外的显着特征,所以......

例外和使用errno的根本区别是什么?

这里有很多差异,很难说从哪里开始。

首先,C 中使用的errno是一个全局变量;这意味着每个调用 errno -set 子例程的例程都必须在执行任何其他工作之前检查errno,如果它关心正确性。幸运的是,errno 是线程安全的。

C++异常会自动展开调用堆栈,直到找到准备好处理错误的函数。这意味着在大多数情况下,用户不必显式检查每个调用是否存在错误;相反,他们可以在一个地方收集错误返回。C++异常可以包含整数以外的值,这与 errno 不同。

你可以随便忽略errno。 必须处理例外情况。

当然,我已经看到了我的份额:

try {
   // something
}
catch( ... ) {
   // nothing
}
// continue as if nothing happened

和(爪哇)

try {
   // something
}
catch( Throwable t ) {
   // nothing
}
// continue as if nothing happened

但至少当你在别人的烂摊子里耕耘时,这种感觉会跳出来。

我觉得

有必要指出,面对异常编写正确的程序并不容易。 你最好对这个主题做一些研究,也许从本周大师开始。 只需寻找exception这个词.

1)异常可以是任何东西,而不仅仅是整数。因此,传达的数据是不同的。

2) 异常执行非本地控制流,因此您不必像在实践中使用 errno 那样在每个级别进行检查,您还返回一个指示错误的值,并且每个调用方都会检查错误并在发生错误时尽早救援。相反,错误返回执行本地控制流,因此您始终可以准确地看到错误何时通过给定代码段传播。这种差异从根本上改变了编码风格。所以沟通的方式也不同。

对我来说

,最重要的区别是errno很容易被忽略,而异常很难被忽视 - 如果你最终忽略它们,程序将终止......另外,异常是(嗯,应该是)对象,因此您可以携带更多有用的信息。

另一个非常重要的区别是,在软件实际上可以做出如何处理问题的明智决策时,可以很容易地处理异常,这通常是调用堆栈的几个级别。使用错误代码并不容易做到。

我发现在嵌入式系统上有用的一种模式是为每个流设置一个错误标志,但前提是在设置标志时尝试的 I/O 操作将立即失败。 因此,代码可以执行以下操作:

 pkt_type = tcp_getbyte(my_stream,超时);  pkt_length = tcp_getbyte(my_stream,超时);  pkt_length |= tcp_getbyte(my_stream,超时) <<8;  如果 (pkt_length <MAX_PACKET_LENGTH)>错误)  {   /* 对数据包做点什么 */ }

如果一次尝试获取字节超时,则后续尝试将无条件失败,返回零。 没有必要检查每个操作是否失败;如果出现问题,系统最终的行为将大致像 tcp_getbyte() 抛出异常一样,只是没有那么快。