【发布时间】:2011-08-24 13:59:24
【问题描述】:
作为一名 C 程序员,我对异常没有太多经验。我更习惯于将errno 作为跨多个函数调用传达错误的一种方式。话虽如此,我没有看到异常的显着特征,所以...
异常和使用errno的根本区别是什么?
【问题讨论】:
-
很简单:忽略异常是完全有效的,不希望如此。它具有出色的定义行为。
作为一名 C 程序员,我对异常没有太多经验。我更习惯于将errno 作为跨多个函数调用传达错误的一种方式。话虽如此,我没有看到异常的显着特征,所以...
异常和使用errno的根本区别是什么?
【问题讨论】:
我发现在嵌入式系统上有用的一种模式是为每个流设置一个错误标志,但前提是在设置标志时尝试的 I/O 操作将立即失败。因此,代码可以执行以下操作:
pkt_type = tcp_getbyte(my_stream, timeout); pkt_length = tcp_getbyte(my_stream, timeout); pkt_length |= tcp_getbyte(my_stream, timeout) 错误) { /* 对数据包做一些事情 */ }如果一次获取字节的尝试超时,后续尝试将无条件失败,返回零。没有必要检查每个操作是否失败;如果出现问题,系统最终会表现得大致就像 tcp_getbyte() 抛出了异常一样,只是没有那么快。
【讨论】:
我不得不指出,面对异常编写正确的程序并不容易。你最好对这个主题做一些研究,也许从Guru of the Week开始。只需查找单词exception。
【讨论】:
你可以随便忽略errno。必须处理异常。
我当然看过我的分享:
try {
// something
}
catch( ... ) {
// nothing
}
// continue as if nothing happened
和(Java)
try {
// something
}
catch( Throwable t ) {
// nothing
}
// continue as if nothing happened
但至少当你在别人的烂摊子里翻滚时,这有点跳出来了。
【讨论】:
对我来说,最重要的区别是errno 很容易被忽略,而异常则很难忽略 - 如果您最终忽略它们,程序将终止......另外,异常是(嗯,应该是)对象,以便您携带更多有用的信息。
另一个非常重要的区别是,异常可以很容易地在软件实际上可以做出明智的决定如何处理问题的时候得到处理,这通常是调用堆栈的几个层次。用错误代码做到这一点并不容易。
【讨论】:
这里有很多不同之处,很难说从哪里开始。
首先,C中使用的errno是一个全局变量;这意味着每个调用errno-setting 子例程的例程都必须在执行任何其他工作之前检查errno,如果它关心正确性。幸运的是,errno is threadsafe。
C++ 异常会自动展开调用堆栈,直到找到准备处理故障的函数。这意味着在大多数情况下,用户不必明确检查每个调用是否有错误。相反,他们可以在一个地方收集错误返回。与 errno 不同,C++ 异常可以包含整数以外的值。
【讨论】:
1) 异常可以是任何东西,而不仅仅是整数。所以传递的数据是不同的。
2) 异常执行非本地控制流,因此您不必像在实践中使用errno 那样检查每个级别,您还返回一个指示错误的值,并且每个调用者都会检查错误和如果发生了,就会提前退出。相反,错误返回执行本地控制流,因此您始终可以准确地看到错误何时通过给定的代码块传播。这种差异从根本上改变了编码风格。所以沟通的方式也不同。
【讨论】: