「goto」によるフロー制御マクロ

エラー処理は、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 を設計すると、リソース管理が大幅に簡素化されます。