Sujet : Re: Opinions on `defer`?
De : ldo (at) *nospam* nz.invalid (Lawrence D'Oliveiro)
Groupes : comp.lang.cDate : 28. Feb 2025, 01:08:01
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vpqup1$3b0j8$2@dont-email.me>
References : 1 2
User-Agent : Pan/0.162 (Pokrosvk)
On Wed, 8 Jan 2025 01:21:08 +0100, Janis Papanagnou wrote:
Using heap objects I typically pass the pointers across function
call boundaries. So it doesn't seem to be useful to me if the
'defer' feature controls just block scopes.
Commonly I will have a function that creates some complex data structure,
which involves multiple dynamic allocations of parts of that structure
which are then joined into the whole. If all those allocations succeed,
then I return a single pointer to the whole object; if any of them fail, I
must clean up everything that was partially allocated.
Interfacing to a highly dynamic language (like Python) makes for a lot of
situations like this. Example below ...
/* informational types to indicate that a pointer is “borrowing” its
reference and doesn’t need to be disposed: */
typedef char
br_char;
typedef PyObject
br_PyObject;
static PyObject * discipline_makedict
(
PyObject * self,
PyObject * args
)
{
PyObject * result = NULL;
PyObject * tempresult = NULL;
br_PyObject * items;
const br_char * msg = NULL;
do /*once*/
{
const bool parsed_ok = PyArg_ParseTuple(args, "Os", &items, &msg);
if (not parsed_ok)
break;
if (not PyTuple_Check(items))
{
PyErr_SetString(PyExc_TypeError, "expecting a tuple");
break;
} /*if*/
const ssize_t nr_items = PyTuple_Size(items);
if (PyErr_Occurred())
break;
tempresult = PyDict_New();
if (tempresult == NULL)
break;
for (ssize_t i = 0;;)
{
if (i == nr_items)
break;
br_PyObject * const item = PyTuple_GetItem(items, i);
if (item == NULL)
break;
if (not PyTuple_Check(item) or PyTuple_Size(item) != 2)
{
PyErr_SetString(PyExc_TypeError, "expecting a 2-tuple");
break;
} /*if*/
br_PyObject * const first = PyTuple_GetItem(item, 0);
if (first == NULL)
break;
br_PyObject * const second = PyTuple_GetItem(item, 1);
if (second == NULL)
break;
if (PyDict_SetItem(tempresult, first, second) < 0)
break;
++i;
} /*for*/
if (PyErr_Occurred())
break;
/* all done */
result = tempresult;
tempresult = NULL; /* so I don’t dispose of it yet */
}
while (false);
Py_XDECREF(tempresult);
return
result;
} /*discipline_makedict*/