エラー処理は、goto
のまれな状況の 1 つです。 それほど悪くありません。
しかし、そのコードを維持しなければならないとしたら、 goto
ということに非常に腹を立てるでしょう。 マクロによって隠されています。
したがって、この場合は goto
私には問題ありませんが、マクロは問題ありません。
goto
の使用 一般的なエラー ハンドラ/クリーンアップ/終了シーケンスに進むことは問題ありません。
このコード:
void func()
{
char* p1 = malloc(16);
if( !p1 )
goto cleanup;
char* p2 = malloc(16);
if( !p2 )
goto cleanup;
cleanup:
if( p1 )
free(p1);
if( p2 )
free(p2);
}
合法的に次のように書くことができます:
void func()
{
char* p1 = malloc(16);
char* p2 = malloc(16);
free(p1);
free(p2);
}
メモリ割り当てが成功するかどうか。
これは、NULL ポインターが渡された場合に free() が何もしないためです。独自の API を設計して他のリソースを割り当てたり解放したりするときに、同じイディオムを使用できます。
// return handle to new Foo resource, or 0 if allocation failed
FOO_HANDLE AllocFoo();
// release Foo indicated by handle, - do nothing if handle is 0
void ReleaseFoo( FOO_HANDLE h );
このような API を設計すると、リソース管理が大幅に簡素化されます。