Почему деструктор объекта C++ не вызывается при вызове luaL_error?

У меня есть такой код

class Test
{
public:
    Test() {printf(">>> Test()\n");}
    ~Test() {printf(">>> ~Test()\n");}
}

int myFunc(lua_State *L)
{
    Test t;
    luaL_error(L, "error");
    return 0;
}

Я знаю, когда lua соблюдает c complier, он использует longjmp, чтобы вызвать ошибку. Итак, я скомпилировал его с использованием компилятора C++, чтобы он использовал исключение C++ для обработки ошибок, и деструктор должен вызываться, даже если выдается ошибка. Но моя проблема в том, что деструктор объекта не вызывается.

Тем не менее, следующий код работает (деструктор называется)

int myFunc(lua_State *L)
{
    Test t;
    throw(1) // just for testing
    return 0;
}

Почему это случилось? Я уверен, что макрос LUAI_THROW интерпретируется как ключевое слово throw.

2 ответа

Решение

Основная причина связана с режимом обработки исключений в компиляторе Visual C++. Я использую функцию lua (например, luaL_error) с модификатором extern "C", чтобы компилятор не искажал имена. И режим обработки исключений по умолчанию - это /EHsc, в котором предполагается, что функция extern "C" не вызывает исключение. Таким образом, исключение не может быть поймано. Решением является изменение /EHsc на /EHs.

Для получения дополнительной информации, пожалуйста, обратитесь к http://msdn.microsoft.com/en-us/library/1deeycx5.aspx.

Функция luaL_error() вызовет функцию exit(), которая отменяет все выполнение вашей программы! Тогда дескриптор не вызывается, потому что область действия Test t не заканчивается. Вы должны использовать другую функциональность, чтобы иметь возможность восстановиться после ошибки.

Как вы называете ошибку от lua? Я думаю, что вам нужно сделать защищенный вызов, используя lua_cpcall, чтобы обойти этот выход при ошибке!

Другие вопросы по тегам