[Info-vax] BASIC (and Horizon)

Arne Vajhøj arne at vajhoej.dk
Wed Jan 31 19:29:14 EST 2024


On 1/31/2024 6:21 PM, Lawrence D'Oliveiro wrote:
> 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.

Goto work fine with nested loops. In fact it is one of the cases
where it really makes sense.

>           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*/

That code would look a lot cleaner if the do while(false) loop got
removed and the relevant breaks got replaced by goto's.

A well named goto label is much more informative than a plain break.

> More details here
> <https://gitlab.com/ldo/a_structured_discipline_of_programming/>.

Truly bad design.

All the code examples would look better with the do while(false) loops
removed and appropriate goto's.

Arne




More information about the Info-vax mailing list