|
|
View previous topic :: View next topic |
Author |
Message |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
To goto or not to goto? That is the question. |
Posted: Wed Feb 25, 2015 3:27 am |
|
|
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
|
|
Posted: Wed Feb 25, 2015 3:58 am |
|
|
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
|
|
Posted: Wed Feb 25, 2015 4:11 am |
|
|
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: 19510
|
|
Posted: Wed Feb 25, 2015 5:17 am |
|
|
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. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Feb 25, 2015 5:25 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Feb 25, 2015 6:29 am |
|
|
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
|
|
Posted: Wed Feb 25, 2015 6:40 am |
|
|
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: 19510
|
|
Posted: Wed Feb 25, 2015 8:33 am |
|
|
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. |
|
|
Arizona Chris
Joined: 20 Dec 2014 Posts: 69 Location: Arizona
|
goto |
Posted: Wed Feb 25, 2015 9:56 am |
|
|
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
|
|
Posted: Wed Feb 25, 2015 10:32 am |
|
|
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.
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Feb 25, 2015 10:41 am |
|
|
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
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Feb 26, 2015 3:14 am |
|
|
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'. |
|
|
|
|
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
|