Windows для профессионалов


Funcenstein4


Рассмотрим еще один сценарий обработки завершения.

DWORD Funcenstein4()
{

DWORD dwTemp;

// 1. Что-то делаем здесь

...

__try
{
// 2. Запрашиваем разрешение на доступ
// к защищенным данным, а затем используем их
WaitForSingleObject(g_hSem, INFINITE);
g_dwProtectedData = 5;
dwTemp = g_dwProtectedData;

// возвращаем новое значение return(dwTemp);
}

__finally
{
// 3. Даем и другим попользоваться защищенными данными
ReleaseSemaphore(g_hSem, 1, NULL);

return(103);
}

// продолжаем что-то делать - этот код
// никогда не выполняется
dwTemp = 9;

return(awTemp);
}

Блок try в Funcenstein4 пытается вернуть значение переменной dwTemp (5) функ ции, вызвавшей Funcenstein4. Как мы уже отметили при обсуждении Funcenstein2, попытка преждевременного возврата из блока try приводит к генерации кода, кото рый записывает возвращаемое значение во временную переменную, созданную ком пилятором. Затем выполняется код в блоке finаllу. Кстати, в этом варианте Funcenstein2 я добавил в блок finаllу оператор return. Вопрос: что вернет Funcenstein4 — 5 или 103? Ответ: 103, так как оператор return в блоке finаllу приведет к записи значения 103 в ту же временную переменную, в которую занесено значение 5. По завершении блока finаllу текущее значение временной переменной (103) возвращается функции, вызвав шей Funcenstein4

Итак, обработчики завершения, весьма эффективные при преждевременном вы ходе из блока try, могут дать нежелательные результаты именно потому, что предотв ращают досрочный выход из блока try. Лучше всего избегать любых операторов, спо собных вызыать преждевременный выход из блока try обработчика завершения. А в идеале — удалить все операторы return, continue, break,goto (и им подобные) как из блоков try, так и из блоков finally. Тогда компилятор сгенерирует код и более компак-. тный (перехватывать преждевременные выходы из блоков try не понадобится), и бо лее быстрый (на локальную раскрутку потребуется меньше машинных команд). Да и читать Ваш код будет гораздо легче.




Начало  Назад  Вперед