作为一名C程序员,我并不具备很多异常处理的经验。我更习惯于使用
errno
来在多个函数调用之间传递错误信息。话虽如此,我并没有看出异常处理的区别,那么...
异常和使用errno
之间的根本区别是什么?
errno
是一个全局变量;这意味着每个调用设置errno
的子程序的例程必须在执行任何其他工作之前检查errno
,如果它关心正确性的话。幸运的是,errno是线程安全的。您可以随意忽略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; if (pkt_length < MAX_PACKET_LENGTH) { for (i=0; i<pkt_length; i++) buffer[i] = tcp_getbyte(my_stream, timeout); } if (!my_stream->error) { /* 对数据包进行处理 */ }
如果尝试获取字节超时,则后续尝试将无条件失败并返回零。不需要检查每个操作是否失败;如果出现问题,系统最终会表现得与tcp_getbyte()抛出异常类似,只是速度稍慢。