简体   繁体   English

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

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

Suppose I have a C library that I'm linking into a C++ program on Windows using Visual Studio. 假设我有一个C库,我使用Visual Studio链接到Windows上的C ++程序。 This C library is black box. 这个C库是黑盒子。 If a fatal error occurs in this library (such as dereferencing a null), how will this runtime error be handled by the program/OS? 如果此库中发生致命错误(例如取消引用null),程序/ OS将如何处理此运行时错误? I know in C++ that there are null reference exceptions, so you can probably handle such errors with a try/catch, but since this is a C library it won't issue a throw , right? 我在C ++中知道存在空引用异常,因此您可以使用try / catch处理此类错误,但由于这是一个C库,它不会发出throw ,对吧? So what will happen? 那会发生什么? The program will terminate, but through what means if not a C++ exception? 该程序将终止,但通过什么方式,如果不是C ++异常?

You can never "handle" dereferencing a null pointer. 您永远不能“处理”取消引用空指针。 Once you do this, your program is no longer in a well-defined state, and there is no way to continue deterministically. 执行此操作后,您的程序将不再处于定义良好的状态,并且无法确定性地继续执行。 The only course of action is to terminate() , which the OS will kindly do on your behalf if you have not registered a SIGSEGV handler. 唯一的操作方法是terminate() ,如果您尚未注册SIGSEGV处理程序,操作系统将代表您进行操作。

The word "error" has several meanings which could possibly be confusing: On the one hand, a function that is unable to perform its expected task may be said to have encountered an "error", and it would be expected to signal this, either through a suitable return value, or by throwing an exception. “错误”这个词有几个含义可能会令人困惑:一方面,一个无法执行其预期任务的功能可能会被称为遇到“错误”,并且可能会发出这样的信号:通过合适的返回值,或通过抛出异常。 This behaviour might better be called a failure . 这种行为最好称为失败 A correct program must be prepared to handle all possible ways in which a function may return. 必须准备一个正确的程序来处理函数可能返回的所有可能方式。 On the other hand, there are programming errors which simply lead to an wrong or even an ill-formed program. 另一方面, 编程错误只会导致错误甚至形成错误的程序。 A correct program must never have any programming errors. 正确的程序绝不能有任何编程错误。

For example, malloc() may fail (if it cannot find enough space), which it signals by returning a null pointer, but your program would be in error if it dereferenced the result of malloc() without checking. 例如, malloc()可能会失败 (如果它找不到足够的空间),它通过返回空指针发出信号,但是如果它取消引用malloc()的结果而没有检查,那么你的程序将会出错。

You can never "catch" or "handle" programming errors with further programming. 通过进一步编程,您永远不会“捕获”或“处理” 编程错误 Instead, a correct program must correctly anticipate and handle all failure conditions of component functions, and recursively a correctly written function must always return in a well-defined manner and signal failure appropriately. 相反,正确的程序必须正确地预测和处理组件功能的所有故障条件 ,并且递归地正确编写的功能必须始终以明确定义的方式返回并且适当地发出信号故障。

Dereferencing a null pointer in native code will cause an "access violation" on Windows, or a "segmentation fault" on Unix/Linux. 在本机代码中取消引用空指针将导致Windows上的“访问冲突”,或Unix / Linux上的“分段错误”。 Different names for the same thing. 同一件事的不同名称。 It's the CPU that detects the error, and it invokes a handler in the operating system, which terminates the process. 它是检测错误的CPU,它调用操作系统中的处理程序,终止进程。

Dereferencing a null reference in a VM-based language (eg .NET or Java) will throw an exception that you can catch. 在基于VM的语言(例如.NET或Java)中取消引用空引用将引发您可以捕获的异常。 That's possible because the VM sits between the program and the CPU, and it can detect the null before trying to actually dereference it. 这是可能的,因为VM位于程序和CPU之间,它可以在尝试实际解除引用之前检测到null。

AC library is native code, so you'll get an access violation. AC库是本机代码,因此您将获得访问冲突。 You'd get the same from a true C++ program, which is also compiled to native code. 您可以从真正的C ++程序中获得相同的结果,该程序也可以编译为本机代码。 But if you're using Managed C++ or C++/CLI, those are variants which compile to CIL and run on the .NET runtime, so you get a NullReferenceException in that case. 但是,如果您使用的是托管C ++或C ++ / CLI,则这些变体可以编译为CIL并在.NET运行时运行,因此在这种情况下会出现NullReferenceException。

Support for 'asynchronous' or 'structured' exceptions (such as an invalid memory access) to be caught using the C++ catch keyword is an MSVC extension to the C++ language. 支持使用C ++ catch关键字捕获的“异步”或“结构化”异常(例如无效的内存访问)是C ++语言的MSVC扩展。

You can catch such exceptions even if they originate from a C function as long as you use the correct compiler option, /EHa : http://msdn.microsoft.com/en-us/library/1deeycx5%28v=VS.100%29.aspx 只要您使用正确的编译器选项/EHa ,即使它们来自C函数,您也可以捕获此类异常: http//msdn.microsoft.com/en-us/library/1deeycx5%28v=VS.100% 29.aspx

You could also choose to use Microsoft's 'structured exception' handling language extension (also available in C), which uses the __try and __except keywords: http://msdn.microsoft.com/en-us/library/swezty51.aspx 您还可以选择使用Microsoft的“结构化异常”处理语言扩展(也可在C中使用),它使用__try__except关键字: http//msdn.microsoft.com/en-us/library/swezty51.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM