[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua error handling and C++
- From: Sam Roberts <sroberts@...>
- Date: Mon, 16 Oct 2006 12:51:05 -0700
On Mon, Oct 16, 2006 at 03:27:30PM -0400, Glenn Maynard wrote:
> longjmp is incompatible with C++ destructors, and will result in leaks.
It is also "incompatible" with malloc/free, this:
> int mybinding(lua_State *L)
> {
> std::string s1 = luaL_checkstring(L, 1);
> std::string s2 = luaL_checkstring(L, 2);
> ...
> }
is same problem as:
int mybinding(lua_State *L)
{
char* s1 = strdup(luaL_checkstring(L, 1));
char* s2 = strdup(luaL_checkstring(L, 2)); // -- leaks s1 on error
...
}
So the techniques used for C code apply equally here, simple is:
int mybinding(lua_State *L)
{
// make checks that may error() so nothing will error() later
luaL_checkstring(L, 1);
luaL_checkstring(L, 2);
...
// allocate resources
std::string s1 = lua_tostring(L, 1);
std::string s2 = lua_tostring(L, 2);
...
// do things that will not error()
....
// free resources
....
}
Other idiom, as Rici (?) suggested and used in the PIL, is to first
create something that WILL be garbage-collected, like a user-data, then
put your two std::string inside the user-data. If lua longjmps out of
your code, lua will still have the UD on the stack, and lua will know it
needs to be garbage collected, and in the __gc metamethod you can
destroy the s1 and s2.
I guess if code is large enough, then refactor into parts of code that
allocates resources, and into a function that uses those resources and
may error(). pcall the function that may error.
Its hard to have the benefits of C++ automatic resource freeing with
exceptions, without paying the costs for exceptions!
Cheers,
Sam