CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

To goto or not to goto? That is the question.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

To goto or not to goto? That is the question.
PostPosted: Wed Feb 25, 2015 3:27 am     Reply with quote

I just want to share what is, for me, an awkward philosophical problem. I am very strongly thinking of using a goto in some code. This is a very rare thing for me, and is causing me some existential angst: http://en.wikipedia.org/wiki/The_Scream#mediaviewer/File:The_Scream.jpg

My application has very specific circumstances: its one-shot code for a battery operated device - a test box. When powered up, it goes through a series of tests then shuts itself down. There is no main loop, i.e. while(TRUE) {}; the code runs once then sleeps (due to running off the end of my code) until power drops. I'm considering using the goto to exit in the event of low battery. Its an error exit situation. It is NOT an error recovery situation, once the error (low battery) has occurred, the code will exit - stack corruption is not an issue.

Using a goto would avoid repeated checking like this:
Code:

if (Batt_Good())
{
   ...
   if (Batt_Good())
   {
      ...
      if (Batt_Good())
      {
         ...
         if (Batt_Good())
         {
         ...
         }
         else
         {
            // Do some battery bad stuff
         }
      }
      else
      {
         // Do some battery bad stuff
      }
   }
   else
   {
      // Do some battery bad stuff
   }
}
else
{
   // Do some battery bad stuff
}


In C# I'd do it as a try-catch-finally block with battery low thrown as an exception, but, unfortunately this is C, not C#, and there isn't any exception mechanism.

I'm not really looking for alternatives - I could sort them out for myself if I really needed to - nor for anyone to talk me out if it. I'm just saying this to somewhat release said angst. I am a firm goto avoider, but just this once, it makes sense, and is simple. It's just that sort of application.


Last edited by RF_Developer on Wed Feb 25, 2015 5:27 am; edited 1 time in total
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 3:58 am     Reply with quote

Many people forbid the use of the goto command as was it a religious rule. I'm a bit more pragmatic in this: discourage new programmers to use it, but when you know what you are doing it can improve code quality.

Your situation is a perfect example for an exception handler, only too bad this isn't supported by the C language. In richer languages the exceptions are implemented on a lower level by goto commands, so in my opinion it is perfectly allowed to create your own exception handler by using a goto.

Go for it and don't feel awkward.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 4:11 am     Reply with quote

ckielstra wrote:
In richer languages the exceptions are implemented on a lower level by goto commands, so in my opinion it is perfectly allowed to create your own exception handler by using a goto.

Go for it and don't feel awkward.


Well, if anything I'm leaning towards using setjmp()/longjmp(), but the principle is the same. Yes, I do feel it is the sort of circumstance where a jump of some kind (though not necessarily the basic goto) is the most appropriate solution.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 5:17 am     Reply with quote

Yes.

The key danger is that goto, can imbalance the stack. If you goto something without understanding how it works and what can happen it is dangerous. It also generally reflects a lack of understanding of code 'flow', since for general programming where code is actually executing and looping, coming out of the loop, or executing the next loop is a better solution. So for 99.9% of jobs I'd say 'don't use goto'. However there are limited, careful situations, where the goto can be the best solution. I have used it on occasions. For example, in a very tightly timed interrupt handler, where I don't want the compiler saving variables, and am handling the stack myself. Your case of a simple tree, rather than looping code, sounds as if it could be one of the 0.1% situations where goto is applicable. Smile
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 5:25 am     Reply with quote

After a bit of searching, I've gone with a pseudo-try-catch block using the macros described in Exceptions in C with Longjmp and Setjmp. That uses setjmp/longjmp in macros to implement something that looks like a try-catch block. I'm using the simple if version as I've only got one error condition - low battery.

This also salves my inner-programmer-ego as I don't get to type goto or jump directly.
temtronic



Joined: 01 Jul 2010
Posts: 9161
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 6:29 am     Reply with quote

I've do not understood the 'never use the 'goto' statement philosophy. Then again I've only been programming since the mid '70s.
It reminds me of the 'which is better Ford vs. Chevy' arguments or what's better ,a power boat or a sailboat?
There is no right answer as it's a matter of choice.
I do want to point out that Microchip has included the 'goto' instruction in EVERY PIC since day one! So if they allow it, why shouldn't we use it?! CCS allows us to use it, so why not? It's just another instruction that allows programmers to cut code and rather efficiently too.

Heck, one could argue that NO high level language should be used for coding PICs, instead ONLY use Assembler, maybe go back to the 'stone age' and 'toggle in' code like we did with PDP-8 boot loaders.

The bottom line is ,whatever method of coding gets you the result you need, is OK by me, life is too short to have a 'goto' war.

For the record, I like Fords better than Chevy though .

Jay
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 6:40 am     Reply with quote

Jay, there's no war here, nor even any sabre-rattling. its a simple matter of finding a code construct that reasonably represents the algorithm I'm trying to implement.

I've also been programming since the seventies, a good few of us have. We are all aware that gotos, or variants thereof are present in practically all processor instruction sets (I personally can't think of any that don't). We are also all aware, or at least we should be, that higher level language flow statements are implemented with lower level goto-type instructions.

Yes, I am fairly "religious" about not using goto-type code in higher level language, but I'm not fanatical. In this case, what I really wanted to use was something akin to a try-catch block as found in languages that implement exception handling. I also didn't want to reach for the "goto" as my first method of doing it. I would have as a last resort, but in the end, prompted by my personal distaste and distrust of gotos in high level language, I found a way of doing what I needed to that, yes, does technically use a form of goto - longjmp, but looks like the control structure I really wanted to use.

From my perspective that's a win all round. Goto-haters get to say, "see, you didn't need to use a goto after all" and goto-acceptors can say, "See, you did use a goto and the sky didn't fall in!"
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 8:33 am     Reply with quote

Yes.

The key thing is if you are writing the code yourself, there is no problem with a goto. However inside a slightly 'higher level' language, it can be dangerous. The problem is how do _you_ know what the state of the stack is at a given point in the code?. The actual code flows 'under the skin' are often not as simple as it may appear from what you have written. It gets even worse in processors with a data stack, and languages that use this. This is why a lot of these do not have a goto at all, instead offering some form of trap ability.

It's worth quoting the section from K&R:

"C provides the infinitely-abusable goto statement, and labels to branch to. Formally the goto is never necessary, and in practise is is almost always easy to write code without it. We have not used goto in this book.
Nevertheless there are a few situations where gotos may find a place. The most common is to abandon processing in some deeply nested structure such as breaking out of two or more loops at once. The break statement cannot be used directly, since it only exits from the innermost loop. Thus:
Code:

  for (...)
  {
     for(...)
     {
         .....
         if (disaster)
             goto error;
     }
   ......
   }
   
error:
   //clean up the mess

This organisation is handy if the error handling code is not trivial, and if errors can occur in several places.

//another example skipped

With a few exceptions like those cited here, code that relies on goto statements is generally harder to understand and to maintain than code without gotos. Although we are not dogmatic about the matter, it does seem that goto statements should be used rarely, if at all."

Says it all really. Smile
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

View user's profile Send private message Visit poster's website

goto
PostPosted: Wed Feb 25, 2015 9:56 am     Reply with quote

Id like to add here that there is one more special case you are at an advantage to use a "goto" statement, when you program in FSM (Finite State Machine) style. For robots - especially the very advanced ones we work with at my job - the program consists of up to a dozen sub programs each with there own loops that are stand alone groups that run separately. When using FSMs, you can jump depending on conditions from one group of code to another, and you may end up in one loop or another for the entire run for hours on end. Traditionally, in most languages you use a GOTO to jump loops or blocks of code to make the robot enter a different "state". I can see it may be possible for small groups of FSMs to use a Switch statement inside a while loop. This may work for small stuff, but in large complex robots you are left with using gotos for much of the code. In universities and academic pursuits like home robotics, this is pretty standard. But I can see in a large company this could make the software really hard to document and follow clearly. Application defines the code! ;)

Chris
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Feb 25, 2015 10:32 am     Reply with quote

GOTO??
I started with and "thought in" terms of assembler for a long time before adopting CCS C.
I'm completely agnostic - even an atheist when it comes to coding.
I wouldn't hesitate to GOTO and it's all about the result anyway.

No need to confess such a sin. I think it is a VIRTUE anyway.
Very Happy Very Happy Very Happy
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 10:41 am     Reply with quote

Unfortunately - this is very much my personal opinion based on observation - these days coding, especially embedded firmware, is seen more and more as just another everyday part of engineering rather than a speciality. In many job specs I see, its just one small part of the job description, alongside FPGA coding, RF design, PCB layout at high frequencies and so on.

Realistically, any engineer able to do all that, and much more seems to often be expected, cannot be a master of them all. I work with a few very capable RF design engineers, but I wouldn't let them with a soldering iron near anything, nor indeed would the company, at least not officially. Likewise, they would not ask me to design a 2KW broadband power combiner (which, I'm told, is relatively simple). One RF guy does dabble in software at home and we use one of his products here. Its plagued with random failures of unrelated bits whenever anything is changed, and we had one of our important customers discover a basic error in the way a certain equipment calibration was being applied. One day, I might get my hands in that code, but I could easily spend months just knowing it into shape. Great at RF for sure... not quite so great at software.

Just look at the folks we get asking what are very basic C questions on this forum. They are not just students, many describe themselves as capable engineers, who have seemingly been given tight deadlines to implement what often seems to be the unimplementable. They must be good at firmware right? It says so on their CV, and surely any engineer can do it? Its easy! ... Yeah, right. :-|

So, yes folks might well be great at robotics, and all power to them and all that, but, well, they might not be all that great at software and firmware.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 25, 2015 1:59 pm     Reply with quote

I have only used 'goto' in one project, to cleanup an error handler
as shown in these two pages:
http://www.cprogramming.com/tutorial/goto.html
http://programmers.stackexchange.com/questions/154974/is-this-a-decent-use-case-for-goto-in-c
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 3:14 am     Reply with quote

It's interesting that the most experienced people here have all used goto, but have all also avoided it except for exceptional circumstances, exactly as K&R originally suggested. It is a tool, but one that must be used with extreme care. The 'infinitely abusable' phrase in the K&R quote makes the point. Habitually using it is likely to increase the risk of disaster. Used with care it is powerful.

It is like a 'get out of jail free' card in a game, that carries with it the risk that you can go straight back to jail it it is used, except from certain points on the board. 'Caveat programmer'.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group