#include <ext/c_object.h>
Provides C-only object-lifetime helpers built around a small header placed before the user object. The macros create typed C structs with matching initializer/finalizer functions and register allocated objects in a scope list so they can be finalized automatically when leaving a safe scope.
object_basestores per-objectcontextandfinalizecallback data.ext_create_object(type)creates a typed object and registers it in the current safe scope.ext_create_object_ex(type, context)does the same while passing a caller context pointer to the initializer.ext_delete_object(object)unregisters, finalizes, frees, and nulls an object pointer.ext_safe_scope({ ... })creates a scope context for automatic cleanup.ext_begin_safe(signature)andext_end_safe()wrap an entire function body in a safe scope.ext_safe_fn(ret, prototype, body)defines asafe_prefixed helper function that owns a safe scope.ext_invoke_safe_fn(fn, ...)invokessafe_fn(...)and registers its returned object in the current safe scope.ext_return_safe(value)finalizes all objects in the scope before returning.ext_return_safe_object(object)returns one object to the caller and finalizes the other objects in the current scope.ext_decl_object_type(type, initializer, finalizer, members)declares a C object type plustype_initializeandtype_finalizefunctions.ext_begin_object_type(type)andext_end_object_type(...)provide the split form for declaring a type.
Define these macros before including <ext/c_object.h> to override allocation
and scope-entry storage:
ext_alloc_object_base(object_size, context)ext_free_object_base(object, context)alloc_scope_entry(size)free_scope_entry(entry)
The test suite uses these hooks to count allocations and verify that safe scopes release every registered object.
- The macros require a safe scope variable named
__scope_context__; create objects only insideext_safe_scope,ext_begin_safe/ext_end_safe, orext_safe_fnbodies. ext_create_objectstoresobject_baseimmediately before the returned object pointer. Useext_delete_object, not rawfree, for objects created by these helpers.ext_return_safe_object(object)transfers exactly one object out of the safe scope. The caller becomes responsible for deleting that returned object in a later safe scope or withext_delete_object.- Initializers receive
(self, context). Finalizers receive onlyself. - This header is C-compatible and is intentionally macro-heavy. Prefer ordinary C++ RAII when writing C++ code.
- C compiler or C++ compiler
malloc/free, unless allocation hooks are overridden
#include <stdlib.h>
#include <ext/c_object.h>
ext_decl_object_type(
sample_object,
{
self->value = context ? *(int *)context : 0;
},
{
self->value = 0;
},
{
int value;
});
ext_begin_safe(int run_sample(void)) {
int initial = 42;
sample_object_ptr object =
ext_create_object_ex(sample_object, &initial);
if (object->value == 42)
ext_return_safe(EXIT_SUCCESS);
ext_return_safe(EXIT_FAILURE);
}
ext_end_safe();ext_safe_fn(sample_object_ptr, make_sample(int value), {
sample_object_ptr object = ext_create_object(sample_object);
object->value = value;
ext_return_safe_object(object);
});