当我为Windows编程C代码时,我应该“默认”使用SEH的__try..__finally块,还是不必要地这样做被认为是一种不好的做法?
换句话说,下面哪一个(例如)被认为是更好的实践,为什么?

HDC hDCCompat = CreateCompatibleDC(hDC);
__try
{
    HBITMAP hBmpCompat = CreateCompatibleBitmap(hDC, ...);
    __try
    {
        SelectObject(hDCCompat, hBmpCompat);
        BitBlt(hDC, ..., hDCCompat, ...);
    }
    __finally { DeleteObject(hBmpCompat); }
}
__finally { DeleteObject(hDCCompat); }


HDC hDCCompat = CreateCompatibleDC(hDC);
HBITMAP hBmpCompat = CreateCompatibleBitmap(hDC, ...);
SelectObject(hDCCompat, hBmpCompat);
BitBlt(hDC, ..., hDCCompat, ...);
DeleteObject(hBmpCompat);
DeleteObject(hDCCompat);

澄清
我忘了提:
我的想法是,如果有人稍后将更多的代码插入到块中(例如从函数的早期返回),我的代码仍然会执行清理,而不是过早退出。所以它应该比其他任何东西都更具预防性。我还是应该避免使用SEH吗?

最佳答案

在我看来,不。不利因素是很多额外的噪音,我看不出有利因素是什么。

SelectObject(hDCCompat, hBmpCompat);
BitBlt(hDC, ..., hDCCompat, ...);

你怎么能指望这些失败呢?例如,__try通过返回__finally(不检查)而不是通过引发SEH异常来报告错误。SEH异常的许多实例都表示一个根本错误是不可恢复的(内存已损坏或发生了逻辑错误,例如向函数或其他对象传递了无效的句柄)。这些类型的错误不能很好地处理,崩溃通常更容易调试。
如果你想让你的代码在早期的回报面前变得健壮(许多C编码标准不鼓励这样做,部分原因是这样的),那么你应该考虑用一种更难以危险的方式修改的方式来构建你的代码。例如。
int f()
{
    int ret;
    Resource r;

    if (!AcquireResource(&r))
        return FAIL;

    ret = FunctionWithLogicAndEarlyReturns(&r);

    CleanupResource(&r);
    return ret;
}

您可以希望,因为这个函数很简单,所以不会有太大的诱惑来添加额外的早期返回,在所谓的“逻辑”函数中的早期返回不会损害对所获取资源的清理。

09-28 11:37