C语言 如何在C中抛出异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2891766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to throw an exception in C?
提问by httpinterpret
I typed this into google but only found howtos in C++,
我把这个输入谷歌,但只在 C++ 中找到了howtos,
how to do it in C?
如何在C中做到这一点?
回答by Brian R. Bondy
There are no exceptions in C. In C the errors are notified by the returned value of the function, the exit value of the process, signals to the process (Program Error Signals (GNU libc)) or the CPU hardware interruption (or other notification error form the CPU if there is)(How processor handles the case of division by zero).
C 中没有例外。在 C 中,错误通过函数的返回值、进程的退出值、进程的信号(程序错误信号(GNU libc))或 CPU 硬件中断(或其他通知)来通知如果存在,则从 CPU 中出错)(处理器如何处理被零除的情况)。
Exceptions are defined in C++ and other languages though. Exception handling in C++ is specified in the C++ standard "S.15 Exception handling", there is no equivalent section in the C standard.
异常是在 C++ 和其他语言中定义的。C++ 中的异常处理在 C++ 标准“S.15 异常处理”中指定,C 标准中没有等效的部分。
回答by vava
In C you could use the combination of the setjmp()and longjmp()functions, defined in setjmp.h. Example from Wikipedia
在 C 中,您可以使用setjmp()和longjmp()函数的组合,在setjmp.h. 维基百科的例子
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp
// was called - making setjmp now return 1
}
void first(void) {
second();
printf("first\n"); // does not print
}
int main() {
if ( ! setjmp(buf) ) {
first(); // when executed, setjmp returns 0
} else { // when longjmp jumps back, setjmp returns 1
printf("main"); // prints
}
return 0;
}
Note:I would actually advise you notto use them as they work awful with C++ (destructors of local objects wouldn't get called) and it is really hard to understand what is going on. Return some kind of error instead.
注意:我实际上建议您不要使用它们,因为它们在 C++ 中工作得很糟糕(不会调用本地对象的析构函数)并且很难理解发生了什么。而是返回某种错误。
回答by Lucas Jones
Plain old C doesn't actually support exceptions natively.
普通的旧 C 实际上本身并不支持异常。
You can use alternative error handling strategies, such as:
您可以使用替代错误处理策略,例如:
- returning an error code
- returning
FALSEand using alast_errorvariable or function.
- 返回错误代码
- 返回
FALSE和使用last_error变量或函数。
See http://en.wikibooks.org/wiki/C_Programming/Error_handling.
请参阅http://en.wikibooks.org/wiki/C_Programming/Error_handling。
回答by Guillermo Calvo
There's no built-inexception mechanism in C; you need to simulateexceptions and their semantics. This is usually achieved by relying on setjmpand longjmp.
C 中没有内置的异常机制;您需要模拟异常及其语义。这通常是通过依赖setjmp和来实现的longjmp。
There are quite a few libraries around, and I'm implementing yet another one. It's called exceptions4c; it's portable and free. You may take a look at it, and compare it against other alternativesto see which fits you most.
周围有很多库,我正在实施另一个库。它被称为exceptions4c;它是便携和免费的。您可以看看它,并将其与其他替代方案进行比较,看看哪个最适合您。
回答by wcy
C is able to throw C++ exception, they are machine codes anyway. For example, in bar.c
C 能够抛出 C++ 异常,无论如何它们都是机器代码。例如,在 bar.c
// begin bar.c
#include <stdlib.h>
#include <stdint.h>
extern void *__cxa_allocate_exception(size_t thrown_size);
extern void __cxa_throw (void *thrown_exception, void* *tinfo, void (*dest) (void *) );
extern void * _ZTIl; // typeinfo of long
int bar1()
{
int64_t * p = (int64_t*)__cxa_allocate_exception(8);
*p = 1976;
__cxa_throw(p,&_ZTIl,0);
return 10;
}
// end bar.c
in a.cc,
在 a.cc 中,
#include <stdint.h>
#include <cstdio>
extern "C" int bar1();
void foo()
{
try{
bar1();
}catch(int64_t x){
printf("good %ld",x);
}
}
int main(int argc, char *argv[])
{
foo();
return 0;
}
to compile it
编译它
gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out
output
输出
good 1976
http://mentorembedded.github.io/cxx-abi/abi-eh.htmlhas more detail info about __cxa_throw.
http://mentorembedded.github.io/cxx-abi/abi-eh.html有关于__cxa_throw.
I am not sure whether it is portable or not, and I test it with 'gcc-4.8.2' on Linux.
我不确定它是否可移植,我在 Linux 上用“gcc-4.8.2”测试它。
回答by Joe
This question is super old, but I just stumbled across it and thought I'd share a technique: divide by zero, or dereference a null pointer.
这个问题非常古老,但我只是偶然发现了它,并认为我会分享一个技巧:除以零,或取消引用空指针。
The question is simply "how to throw", not how to catch, or even how to throw a specific type of exception. I had a situation ages ago where we needed to trigger an exception from C to be caught in C++. Specifically, we had occasional reports of "pure virtual function call" errors, and needed to convince the C runtime's _purecall function to throw something. So we added our own _purecall function that divided by zero, and boom, we got an exception that we could catch on C++, and even use some stack fun to see where things went wrong.
问题只是“如何抛出”,而不是如何捕捉,甚至如何抛出特定类型的异常。很久以前,我遇到过一种情况,我们需要从 C 触发异常以在 C++ 中捕获。具体来说,我们偶尔会报告“纯虚函数调用”错误,并且需要说服 C 运行时的 _purecall 函数抛出一些东西。所以我们添加了我们自己的 _purecall 函数,它被零除,然后轰隆一声,我们得到了一个异常,我们可以在 C++ 上捕获它,甚至使用一些堆栈乐趣来查看哪里出了问题。
回答by Donal Fellows
On Win with MSVCthere's __try ... __except ...but it's really horrible and you don't want to use it if you can possibly avoid it. Better to say that there are no exceptions.
在 Win with MSVC 上有,__try ... __except ...但它真的很可怕,如果你可以避免它,你不想使用它。最好说没有例外。
回答by Joe
C doesn't have exceptions.
C 没有例外。
There are various hacky implementations that try to do it (one example at: http://adomas.org/excc/).
有各种 hacky 实现试图做到这一点(一个例子在:http: //adomas.org/excc/)。
回答by user3510229
As mentioned in numerous threads, the "standard" way of doing this is using setjmp/longjmp. I posted yet another such solution to https://github.com/psevon/exceptions-and-raii-in-cThis is to my knowledge the only solution that relies on automatic cleanup of allocated resources. It implements unique and shared smartpointers, and allows intermediate functions to let exceptions pass through without catching and still have their locally allocated resources cleaned up properly.
正如在许多线程中提到的,这样做的“标准”方法是使用 setjmp/longjmp。我向https://github.com/psevon/exceptions-and-raii-in-c发布了另一个这样的解决方案,据 我所知,这是唯一依赖于自动清理分配资源的解决方案。它实现了独特且共享的智能指针,并允许中间函数让异常通过而不会被捕获,并且仍然正确清理了其本地分配的资源。
回答by Mahmoud Al-Qudsi
C doesn't support exceptions. You can try compiling your C code as C++ with Visual Studio or G++ and see if it'll compile as-is. Most C applications will compile as C++ without major changes, and you can then use the try... catch syntax.
C 不支持异常。您可以尝试使用 Visual Studio 或 G++ 将 C 代码编译为 C++,看看它是否会按原样编译。大多数 C 应用程序无需重大更改即可编译为 C++,然后您可以使用 try...catch 语法。

