作为一名 C 程序员,我对异常没有太多经验。我更习惯于errno
作为跨多个函数调用传达错误的一种方式。话虽如此,我没有看到异常的显着特征,所以......
异常和使用之间的根本区别是什么errno
?
这里有很多差异,很难说从哪里开始。
首先,errno
在 C 中使用的是全局变量;这意味着每个调用errno
-setting 子例程的例程都必须errno
在执行任何其他工作之前检查它是否关心正确性。幸运的是,errno 是线程安全的。
C++ 异常会自动展开调用堆栈,直到找到准备处理故障的函数。这意味着在大多数情况下,用户不必明确检查每个调用是否有错误。相反,他们可以在一个地方收集错误返回。与 errno 不同,C++ 异常可以包含整数以外的值。
我不得不指出,面对异常编写正确的程序并不容易。你最好对这个主题做一些研究,也许从本周的 Guru开始。只是寻找这个词exception
。
你可以随便忽略errno。必须处理异常。
当然,我已经看到了我的份额:
try {
// something
}
catch( ... ) {
// nothing
}
// continue as if nothing happened
和(Java)
try {
// something
}
catch( Throwable t ) {
// nothing
}
// continue as if nothing happened
但至少当你在别人的烂摊子里翻滚时,你会觉得有点不对劲。
1) 异常可以是任何东西,而不仅仅是整数。所以传递的数据是不同的。
2) 异常执行非本地控制流,因此您不必像在实践中那样检查每个级别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) << 8; 如果(pkt_length < MAX_PACKET_LENGTH) { 对于 (i=0; i<pkt_length; i++) 缓冲区[i] = tcp_getbyte(my_stream, timeout); } 如果(!my_stream->错误) { /* 对数据包做一些事情 */ }
如果一次尝试获取字节超时,则后续尝试将无条件失败,返回零。没有必要检查每个操作是否失败;如果出现问题,系统最终会表现得大致就像 tcp_getbyte() 抛出了异常一样,只是没有那么快。