[Info-vax] BASIC (and Horizon)
Lawrence D'Oliveiro
ldo at nz.invalid
Wed Jan 31 18:21:34 EST 2024
On Wed, 31 Jan 2024 17:08:44 -0500, Arne Vajhøj wrote:
> On 1/31/2024 4:28 PM, Lawrence D'Oliveiro wrote:
>
>> I have never written a goto in C code (not production code, anyway). These
>> days, you need to do so much dynamic allocation, there is nearly always
>> some need for cleanup when exiting an inner block anyway, so you can’t
>> just jump directly somewhere else first. The overall pattern looks like
>> this:
>>
>> MyPtr obj = NULL;
>> do /*once*/
>> {
>> ... possible other stuff ...
>> «allocate memory for obj»;
>> if («error occurred»)
>> break;
>> ... possible other stuff using obj ...
>> }
>> while (false);
>> free(obj);
>>
>> You can confirm, just by inspection, that there is no path out of the
>> block that does not pass through the free() call precisely once.
>
> And the difference compared to:
>
> MyPtr obj = NULL;
> ... possible other stuff ...
> «allocate memory for obj»;
> if («error occurred»)
> goto lbl_freeobj;
> ... possible other stuff using obj ...
> lbl_freeobj:
> free(obj);
>
> are?
Nesting. Try to scale up to something like
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;
fprintf(stdout, "makedict says: “%s”\n", msg);
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 (first == (PyObject *)&ExceptMe_type or second == (PyObject *)&ExceptMe_type)
{
PyErr_SetString(PyExc_ValueError, "ExceptMe object found");
break;
} /*if*/
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*/
More details here
<https://gitlab.com/ldo/a_structured_discipline_of_programming/>.
More information about the Info-vax
mailing list