异常与errno的区别

4
作为一名C程序员,我并不具备很多异常处理的经验。我更习惯于使用errno来在多个函数调用之间传递错误信息。话虽如此,我并没有看出异常处理的区别,那么...

异常和使用errno之间的根本区别是什么?


非常简单:忽略异常是完全有效的,甚至是期望的。它具有良好的定义行为。 - Hans Passant
6个回答

5
这里有很多不同之处,很难说从哪里开始。
首先,在C语言中使用的errno是一个全局变量;这意味着每个调用设置errno的子程序的例程必须在执行任何其他工作之前检查errno,如果它关心正确性的话。幸运的是,errno是线程安全的
C++异常会自动展开调用堆栈,直到找到一个准备好处理故障的函数。这意味着在大多数情况下,用户不必明确地检查每个调用是否出错;相反,他们可以在一个地方收集错误返回。与errno不同,C++异常可以包含除整数以外的值。

3

我觉得有必要指出,在面对异常情况时编写正确的程序并不容易。你最好在这个主题上进行一些研究,也许可以从本周大师开始。只需查找单词exception


3

您可以随意忽略errno。必须处理异常。

当然,我也见过自己的困难:

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

并且(Java)

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

但至少当你在处理别人的混乱时,这种情况容易被注意到。

2

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

2) 异常执行非局部控制流,这样你就不必在每个级别上都进行检查,而在实践中使用errno时,你还返回一个指示错误的值,并且每个调用者都会检查错误并在出现错误时尽早退出。相反,错误返回执行局部控制流,因此你总是能够准确地看到错误是如何通过给定的代码块传播的。这种差异彻底改变了编码风格。因此,所使用的通信方式也是不同的。


2
对我而言,最重要的区别是 errno 很容易被忽略,而异常很难被忽略——如果你忽略了它们,程序就会终止…此外,异常(应该)是对象,因此你可以携带更多有用的信息。
另一个非常重要的区别是,异常可以在软件能够做出知情决策的地方轻松处理问题,这通常位于调用栈的几个级别上。使用错误代码做到这一点并不容易。

1

在嵌入式系统中,我发现有一个有用的模式是为每个流设置一个错误标志,但是当设置了标志时,提供一个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()抛出异常类似,只是速度稍慢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接