gotoプログラミングのすゝめ
ある人が作っていたBREWのアプリのソースを、自分が引き継いだ訳なんだけれども、これがめちゃめちゃ凄い。
こんな感じになってる。
int foo( CHoge* pMe , char* pFileName ){ int ret; int ret2; IFileMgr* pIFileMgr; IFile* pIFile; FileInfo fileInfo; char* pData; ret2 = ISHELL_CreateInstance( pMe->a.m_pIShell , AEECLSID_FILEMGR , (void **)(&pIFileMgr) ); if( ret2 != SUCCESS ){ ret = EFAILED; return ret; } pIFile = IFILEMGR_OpenFile( pIFileMgr , pFileName , _OFM_READ ); if( pIFile == NULL ){ IFILEMGR_Release( pIFileMgr ); pIFileMgr = NULL; ret = EFAILED; return ret; } ret2 = IFILE_GetInfo( pIFile , &fileInfo ); if( ret2 != SUCCESS ){ IFILE_Release( pIFile ); pIFile = NULL; IFILEMGR_Release( pIFileMgr ); pIFileMgr = NULL; ret = EFAILED; return ret; } size = fileInfo.dwSize; pData = MALLOC( size + 1 ); if( pData == NULL ){ IFILE_Release( pIFile ); pIFile = NULL; IFILEMGR_Release( pIFileMgr ); pIFileMgr = NULL; ret = EFAILED; return ret; } ret2 = IFILE_Read( pIFile , pData , size ); if( (uint32)ret2 != size ){ FREE( pData ); pData = NULL; IFILE_Release( pIFile ); pIFile = NULL; IFILEMGR_Release( pIFileMgr ); pIFileMgr = NULL; ret = EFAILED; return ret; } // なんかの処理 ret = SUCCESS; FREE( pData ); pData = NULL; IFILE_Release( pIFile ); pIFile = NULL; IFILEMGR_Release( pIFileMgr ); pIFileMgr = NULL; return ret; }
……まじで勘弁して(;´Д`)
失敗するたびに、使用しているリソースを全て解放してからreturnしてます。
おかげで似たような処理が大量に埋め込まれてます。
で、ここを編集しないといけなくなったんだけど、こんなの見てられるか!
ってことで修正。
#define SAFE_SHELL_RELEASE( name , p ) \ if( p != NULL ){ \ name##_Release( p ); \ p = NULL; \ } #define SAFE_RELEASE( p ) \ if( p != NULL ){ \ FREE( p ); \ p = NULL; \ } int foo( CHoge* pMe , char* pFileName ){ int ret; IFileMgr* pIFileMgr; IFile* pIFile; FileInfo fileInfo; char* pData; int ret2; int size; ret = EFAILED; pIFileMgr = NULL; pIFile = NULL; pData = NULL; ret2 = ISHELL_CreateInstance( pMe->a.m_pIShell , AEECLSID_FILEMGR , (void**)(&pIFileMgr) ); if( ret2 != SUCCESS ) goto release; pIFile = IFILEMGR_OpenFile( pIFileMgr , pFileName , _OFM_READ ); if( pIFile == NULL ) goto release; ret2 = IFILE_GetInfo( pIFile , &fileInfo ); if( ret2 != SUCCESS ) goto release; size = fileInfo.dwSize; pData = MALLOC( size + 1 ); if( pData == NULL ) goto release; ret2 = IFILE_Read( pIFile , pData , size ); if( (uint32)ret2 != size ) goto release; // なんかの処理 ret = SUCCESS; release:; SAFE_RELEASE( pData ); SAFE_SHELL_RELEASE( IFILE , pIFile ); SAFE_SHELL_RELEASE( IFILEMGR , pIFileMgr ); return ret; }
はふー。落ち着いた。
gotoってやっぱり便利ですねヽ(´ー`)ノ