C Programming -- Safe recursion in embedded systems
Courtesy https://imgur.com/user/stevencruz3008

C Programming -- Safe recursion in embedded systems

Why does the goto statement even exist in C?

In school, it is often taught that one should never use a goto statement in C code. I had several classes where its use would be an automatic F on the assignment. So why does it even exist if it's so awful? Is there anything that it can be useful for?

Historically it exists for compatibility with Assembler, it's predecessor and foundation. Assembler provides a variety of Jump operators and while C was envisioned as being, and is, much better for human understanding, it has to coexist with legacy and future Assembly code.

Thus the goto/jmp that throws your Program Counter off into the cosmos hoping it runs into a return before encountering the void somewhere along the way, which is why nearly every professor will teach you not to use it. And I agree, in general. There are, however, a few exceptions. That said, "with great power comes great responsibility yadda yadda sudo".

The first of those exceptions is for the original purpose of goto/jmp -- calling a hardware-optimized function written in Assembler. Common examples might be sampling an ADC or RF where you need to take as many samples per second as possible while allowing other threads to also operate -- every CPU clock cycle matters when you're doing eight things at once.

The second is an out-of-box use of goto. A few weeks ago, I posted a job interview question I was once asked. Rewrite a common recursive tree search without increasing the stack. Unlike a function call, goto doesn't add to the stack. How could that be exploited to solve this problem?

This is what I was given to rewrite:

ptr *recursiveFind(const int data, ptr *tree)
{
   ptr *tmp;
   if (NULL == tree) return NULL;
   else if (data == tree->data) return tree;
   else
   {
      if (NULL != (tmp = find(data, tree->left)) || NULL != (tmp = find(data, tree->right))) return tmp;
      else return NULL;
   }
}        



And the solution I gave as an answer:

ptr *noStackFind(const int data, ptr *tree)
{
   ptr *tmp = tree;

   if (NULL == tmp) return NULL;  /* Only possible for root. */
nextLevel:
   if (data == tmp->data) return tmp; 
   else
   {
      if (NULL != tmp->left)
      {
         tmp = tmp->left;
         goto nextLevel;
      }
      if (NULL != tmp->right)
      {
         tmp = tmp->right;
         goto nextLevel;
      }
      return NULL;
   }
}        

Judicious use of goto can allow searching large amounts of static data without ever risking running out of memory, crashing the device, or jeopardizing your career.

The goto code won't find the subtree with the data if the subtree is to the right of the root and there's any data to the left of the root. Here's a demonstration that looks for 5 in the tree 1 / \ 2 5 / \ 3 4 https://godbolt.org/z/39EfKqTzM

Like
Reply

To view or add a comment, sign in

More articles by Richard Law

Others also viewed

Explore content categories