Stuff on software

Posted on Jan 8, 2025

I’m reassessing my choices in my C language library to handle exceptions; at my age I still have not found the definitive way to do it, with the right mechanism and the right names as identifiers; I suck at software engineering.

Many years ago I read cover–to–cover the book:

Alan Burns, Andy Wellings. “Real–Time Systems and Programming Languages”. Details forgotten, but probably second edition.

it was a mistake to spend so much time on that; but I did it nevertheless. (I mean… I read cover–to–cover the manual of the HP 48 handheld calculator; so what!?)

The one thing that stuck in my head is an abstract model for exceptions that the book helped me assemble; I do not know if the authors would approve it; right or wrong does not even matter: it is the only model that stuck in my head. It goes like this:

  1. there are only two kinds of exceptions: logic and runtime;
  2. logic exceptions do not happen in error–free software running on error–free hardware when no cosmic rays flip bits at random;
    • liveness is important: it is better if non–simple software is resilient to logic errors;
  3. everything else is a runtime exception;
    • it is always possible to build an abstract model in which a runtime exception is a synchronisation error:
      1. two processes have a rendez–vous in time with the purpose of establishing a common value for a state; in some situations the new desired state is selected by one of the processes;
      2. if the rendez–vous is terminated successfully: life is good, every process moves on with the same information about the state;
      3. otherwise an error happened; let’s try something else;
    • there is nothing a process can do to make it impossible for runtime exceptions to happen.

Simple example (it looks simple, it has hell inside): a process calls the standard C language function malloc(), there is a rendez–vous between the process and the memory allocator implemented by the operating system.

I need to keep my ideas in good order; otherwise I can do nothing. I would really like to write code in which this abstract model is recognisable. It is simple to organise a tree hierarchy of exceptional–condition objects having 2 main branches: the logic errors; the runtime exceptions. It is hard to effectively implement the rendez–vous idea without making the code too heavy to write; I never really succeeded.

The closest I got, in my opinion, was when I used Scheme syntaxes to attempt an implementation of the “compensations” mechanism described in section 7 of:

Westley Weimer, George C. Necula. “Finding and Preventing Run–Time Error Handling Mistakes”. In Proceedings of the ACM Conference on Object–Oriented Programming, Systems, Languages, and Applications, 2004.

under Scheme languages we can do it on top of the with-exception-handler, dynamic-wind and lambda syntaxes. The short version of it is:

(with-compensations
  (do-something)
  (compensate
      (open-this-thing)
    (with
      (close-this-thing)))
  (do-something-else))

it is hard to do it in non–Lispy languages.

One thing I want to add is the idea of exception handler function that is called by raise without rolling back the stack; only if the exception handler fails to handle, the stack is unwound. This also comes from Scheme.

What I’m doing now is procrastinating day after day, because I do not know; what does “good enough” actually mean?