マクロ内の戻り値を取得

下記のような、「終了処理」+「ハンドルやポインタにNULLを代入」という一連の処理を行うマクロのお話です。

#define  SAFE_CLOSEHANDLE(h)  if((h) != NULL){CloseHandle(h); (h) = NULL;}

この手のマクロは便利ですが、このままでは終了処理関数(ここではCloseHandle())の結果がどうだったのかがわかりません。
下記のように使いたい時もあります。

        :

    if(!SAFE_CLOSEHANDLE(hOge))
    {
         // 失敗した時の処理
    }

        :

マクロ内でif文を使わずに、以下のようにすれば CloseHandle() が成功したか否かを判断できます。

#define  SAFE_CLOSEHANDLE(h)  ((BOOL)(((h) != NULL) ? (CloseHandle(h) != 0 ? (((h) = NULL) == NULL) : (((h) = NULL) != NULL)) : TRUE))

ハンドル h に NULL を代入する際、下線部のように CloseHandle()の結果によって代入後の値とうまく比較してやることで TRUE や FALSE を返せるようになります。

ここでは、マクロ呼び出し時にハンドル h が NULL の場合は SAFE_CLOSEHANDLE は TRUE を返すようにしています。
また、もしCloseHandle()に失敗した場合にハンドル h にNULLを代入したくない場合は、最後の「(((h) = NULL) != NULL)」を「FALSE」にします。

もしハンドルの初期値がINVALID_HANDLE_VALUE(長くなって読み辛いので、IHVとします)など、NULL以外の場合は以下のようにします。

#define  SAFE_CLOSEHANDLE_IHV(h)  ((BOOL)(((h) != IHV) ? (CloseHandle(h) != 0 ? (((h) = IHV) == IHV) : (((h) = IHV) != IHV)) : TRUE))


2008.11.08

ETCトップへ