私はこれをグーグルに入力しましたが、C ++でのハウツーしか見つかりませんでした、
Cでそれを行う方法?
私はこれをグーグルに入力しましたが、C ++でのハウツーしか見つかりませんでした、
Cでそれを行う方法?
回答:
Cには例外はありません。Cでは、関数の戻り値、プロセスの終了値、プロセスへのシグナル(プログラムエラーシグナル(GNU libc))またはCPUハードウェア割り込み(またはその他の通知)によってエラーが通知されます。CPUからのエラー(ある場合)(プロセッサがゼロによる除算の場合をどのように処理するか)。
ただし、例外はC ++およびその他の言語で定義されています。C ++での例外処理は、C ++標準の「S.15例外処理」で指定されており、C標準には同等のセクションはありません。
main
は.c
C ++が含まれている可能性があるため、例外がスローされてプログラムでキャッチされる可能性がありますが、例外のスローとキャッチがCで記述された関数に依存することが多いことを除いて、Cコード部分はこのすべてのことを知らないままです。 C ++ライブラリにあります。Cが使用されているのは、呼び出された関数throw
自体が例外をスローする必要があるリスクを冒すことができないためです。ただし、例外をスロー/キャッチするためのコンパイラ/ライブラリ/ターゲット固有の方法がある場合があります。ただし、クラスインスタンスをスローすることには、それ自体に問題があります。
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;
}
注:私は実際にお勧めします、C ++でひどく機能し(ローカルオブジェクトのデストラクタが呼び出されない)、何が起こっているのかを理解するのが非常に難しいため、使用しないことを。代わりに何らかのエラーを返します。
if()
ます。そこには危険が見えません。ここにいる他の人はいますか?
プレーンな古いCは、実際には例外をネイティブでサポートしていません。
次のような代替のエラー処理戦略を使用できます。
FALSE
を返し、使用するlast_error
。http://en.wikibooks.org/wiki/C_Programming/Error_handlingを参照してください。
GetLastError()
、Windows APIで。
Cには組み込みの例外メカニズムはありません。例外とそのセマンティクスをシミュレートする必要があります。これは通常setjmp
、longjmp
ます。
かなりの数のライブラリが周りにあり、私はさらに別のライブラリを実装しています。これはexceptions4cと呼ばれます。ポータブルで無料です。あなたはそれを見て、それを他の代替物と比較して、どれがあなたに最も合うかを見ることができます。
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
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」でテストしました。
_ZTII
typeinfo for long
例えばを意味しecho '_ZTIl' | c++filt
ます。これは、g ++マングリング方式です。
この質問は非常に古いですが、私はそれを偶然見つけて、ゼロで除算するか、nullポインターを逆参照するテクニックを共有したいと思いました。
問題は、単に「スローする方法」であり、キャッチする方法ではなく、特定のタイプの例外をスローする方法です。私は昔、C ++でキャッチされるようにCからの例外をトリガーする必要がある状況にありました。具体的には、「純粋な仮想関数呼び出し」エラーが時々報告され、Cランタイムの_purecall関数が何かをスローするように説得する必要がありました。そこで、ゼロで除算した独自の_purecall関数を追加してブームし、C ++でキャッチできる例外を取得しました。さらに、スタックの楽しみを使用して、問題が発生した場所を確認しました。
MSVCでのWinには__try ... __except ...
ありますが、それは本当にひどいものであり、回避できる場合は使用しないでください。例外はないと言ったほうがいいです。
Cには例外はありません。
それを行おうとするさまざまなハックな実装があります(例:http : //adomas.org/excc/)。
多くのスレッドで言及されているように、これを行う「標準」の方法は、setjmp / longjmpを使用することです。私 はhttps://github.com/psevon/exceptions-and-raii-in-cにそのような別のソリューションを投稿しました。これは、割り当てられたリソースの自動クリーンアップに依存する唯一のソリューションです。一意の共有スマートポインタを実装し、中間機能が例外をキャッチせずに通過できるようにし、ローカルに割り当てられたリソースを適切にクリーンアップします。
Cは例外をサポートしていません。CコードをC ++としてVisual StudioまたはG ++でコンパイルして、そのままコンパイルされるかどうかを確認できます。ほとんどのCアプリケーションは、大きな変更なしでC ++としてコンパイルされ、try ... catch構文を使用できます。
ハッピーパスデザインパターン(つまり、組み込みデバイス用)を使用してコードを記述する場合、演算子「goto」を使用して例外エラー処理(別名、延期または最終的にエミュレーション)をシミュレートできます。
int process(int port)
{
int rc;
int fd1;
int fd2;
fd1 = open("/dev/...", ...);
if (fd1 == -1) {
rc = -1;
goto out;
}
fd2 = open("/dev/...", ...);
if (fd2 == -1) {
rc = -1;
goto out;
}
// Do some with fd1 and fd2 for example write(f2, read(fd1))
rc = 0;
out:
//if (rc != 0) {
(void)close(fd1);
(void)close(fd2);
//}
return rc;
}
実際には例外ハンドラではありませんが、機能の終了時にエラーを処理する方法を提供します。
PS gotoは、同じまたはより深いスコープからのみ慎重に使用し、変数宣言をジャンプしないでください。