如何在C中抛出exception?
我input这个谷歌,但只发现在C ++ howtos,
如何在C中做到这一点?
在C ++和其他语言中定义的例外中没有例外。
C ++中的exception处理是在C ++标准“S.15exception处理”中规定的,在C标准中没有等同的部分。
在C中,可以使用setjmp.h
定义的setjmp()
和longjmp()
函数的组合。 来自维基百科的例子
#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; }
注意:我实际上build议你不要使用它们,因为它们会使用C ++(本地对象的析构函数不会被调用),而且很难理解正在发生的事情。 返回某种错误,而不是。
普通的旧C实际上并不支持本地的exception。
您可以使用其他error handling策略,例如:
- 返回一个错误代码
- 返回
FALSE
并使用last_error
variables或函数。
见http://en.wikibooks.org/wiki/C_Programming/Error_handling 。
C中没有内置的exception机制; 你需要模拟exception和它们的语义。 这通常通过依赖setjmp
和longjmp
来实现。
有相当多的图书馆,我正在执行另一个。 这就是所谓的exceptions4c ; 它是便携式和免费的。 你可以看看它,并将其与其他替代方法进行比较,看看哪个最适合你。
C没有例外。
有各种hacky实现,试图做到这一点(一个例子在: http : //adomas.org/excc/ )。
在MSVC的Win上有_try ... __except ...
但它真的很可怕,如果你可以避免的话,你不想使用它。 更好地说,没有例外。
这个问题已经超旧了,但是我偶然发现了这个问题,并且认为我会分享一个技巧:除以零,或者取消引用空指针。
问题只是“如何抛出”,而不是如何捕捉,甚至是如何抛出特定types的exception。 我有一个很久以前的情况,我们需要触发一个C的exception被C ++捕获。 具体而言,我们偶尔会报告“纯虚函数调用”错误,并需要说服C运行时的_purecall函数抛出一些东西。 所以我们添加了我们自己的_purecall函数,除以零,繁荣,我们得到一个exception,我们可以捕捉到C ++,甚至使用一些堆栈的乐趣,看看哪里出了问题。
C不支持exception。 你可以尝试使用Visual Studio或者G ++将你的C代码编译为C ++,看看它是否按照原样编译。 大多数C应用程序将作为C ++进行编译而不做重大更改,然后可以使用try … catch语法。
正如在许multithreading中提到的那样,这样做的“标准”方法是使用setjmp / longjmp。 我发布了另一个这样的解决schemehttps://github.com/psevon/exceptions-and-raii-in-c这是我所知的唯一的解决scheme,依靠自动清理分配的资源。 它实现了独特的共享智能指针,并允许中间函数使exception通过而不会捕获,并且仍然可以正确清理其本地分配的资源。
C能够抛出C ++exception,反正他们是机器代码。 例如,在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
在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; }
编译它
gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out
产量
good 1976
http://mentorembedded.github.io/cxx-abi/abi-eh.html有关于;__cxa_throw
更多详细信息。
我不确定它是否可移植,我在Linux上使用'gcc-4.8.2'进行testing。