如何在c++编译的C库中处理运行时错误

How are runtime errors handled in a C library compiled in C++?

本文关键字:处理 运行时错误 c++ 编译      更新时间:2023-10-16

假设我有一个C库,我使用Visual Studio将其链接到Windows上的c++程序中。这个C库是黑盒。如果这个库中发生了致命错误(比如取消对null的引用),程序/操作系统将如何处理这个运行时错误?我知道在c++中有空引用异常,所以你可能可以用try/catch来处理这样的错误,但因为这是一个C库,它不会发出throw,对吧?那么会发生什么呢?程序将终止,但如果不是c++异常,通过什么方式终止?

永远不能"处理"对空指针的解引用。一旦这样做,您的程序就不再处于定义良好的状态,并且无法确定地继续下去。唯一的操作方法是terminate(),如果您没有注册SIGSEGV处理程序,操作系统将善意地代表您执行此操作。

"error"一词有几种可能令人困惑的含义:一方面,一个不能执行预期任务的函数可以说遇到了"错误",并且它应该通过适当的返回值或抛出异常来发出这个信号。这种行为最好被称为故障。一个正确的程序必须准备好处理函数可能返回的所有可能的方式。另一方面,也存在编程错误,它们只会导致错误的甚至是病态的程序。一个正确的程序不应该有任何编程错误。

例如,malloc()可能失败(如果它找不到足够的空间),它通过返回一个空指针来表示,但是如果它在没有检查的情况下解引用malloc()的结果,您的程序将会出错。

您永远无法"捕获"或"处理"编程错误。相反,正确的程序必须正确地预测和处理组件函数的所有故障条件,并且递归地,正确编写的函数必须始终以良好定义的方式返回并适当地表示故障。

在本地代码中取消空指针的引用将导致Windows上的"访问冲突",或Unix/Linux上的"分段错误"。同一件事有不同的名字。CPU检测到错误,并调用操作系统中的处理程序,该处理程序终止进程。

在基于虚拟机的语言(例如。net或Java)中解引用空引用会抛出一个你可以捕获的异常。这是可能的,因为VM位于程序和CPU之间,它可以在尝试实际上解引用它之前检测到null。

一个C库是本地代码,所以你会得到一个访问冲突。您将从真正的c++程序中获得相同的结果,该程序也被编译为本机代码。但如果你使用的是Managed c++或c++/CLI,这些都是编译成CIL并在。net运行时上运行的变体,所以在这种情况下你会得到一个NullReferenceException

支持使用c++ catch关键字捕获的'异步'或'结构化'异常(例如无效的内存访问)是对c++语言的MSVC扩展。

只要使用正确的编译器选项/EHa: http://msdn.microsoft.com/en-us/library/1deeycx5%28v=VS.100%29.aspx

,即使它们来自C函数,也可以捕获此类异常。

你也可以选择使用微软的"结构化异常"处理语言扩展(也可以在C语言中使用),它使用__try__except关键字:http://msdn.microsoft.com/en-us/library/swezty51.aspx