GetLastError, вызываемый в блоке catch, дает неверное значение
Забавно изучать какой-то устаревший код сегодня. Наткнулся на этот маленький номер:
function Func1()
{
DWORD dwError;
try
{
dwError = 1;
throw "Hey!";
} catch (LPCTSTR szError)
{
Log("Log1: %d", dwError);
SetLastError(dwError);
throw szError;
}
}
function Func2()
{
try {
Func1();
}
catch (LPCTSTR szError)
{
DWORD dwLastError = GetLastError();
Log("Log2: %d", dwLastError); ///OMG is 0!
}
}
GetLastError()
возвращает 0! Это почему? Функции на самом деле немного сложнее, чем это. Они включают в себя несколько вещей в стеке (DWORD, CString, BYTE[]). Что я должен искать?
Логи выглядят так:
Log1: 1
Log2: 0
1 ответ
Решение
Исключения C++ в компиляторе MSVC и среде исполнения построены на основе родного Windows SEH. Разматывание стека фактически выполняется Windows. Использование API-функций Windows повлияет на значение, сохраненное для GetLastError(). Подробнее о связи с SEH в этом ответе.