Discussion in "General help Guidance and Discussion" started by    DavesGarage    Nov 7, 2009.
Sat Nov 07 2009, 02:48 AM
#1
At the behest of our website owner, I decided to open a forum thread on software programming techniques. I have been writing software for about 25 years now, and I find I am constantly learning new and innovative ways to get into trouble with my code...

I thought this could be a place where we discuss specific topics - this particular thread is dedicated to the use of GOTO, which is defined within K&R's "The C Programming Language" book as follows:

3.8 Goto and labels
C provides the infinitely-abusable goto statement, and labels to branch to. Formally, the goto statement is never necessary, and in practice it 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: 

       for ( ... )
           for ( ... ) {
               ...
               if (disaster)
                   goto error;
           }
       ...
   error:
       /* clean up the mess */
This organization is handy if the error-handling code is non-trivial, and if errors can occur in several places. 
A label has the same form as a variable name, and is followed by a colon. It can be attached to any statement in the same function as the goto. The scope of a label is the entire function. 
As another example, consider the problem of determining whether two arrays a and b have an element in common. One possibility is 

       for (i = 0; i < n; i++)
           for (j = 0; j < m; j++)
               if (a[i] == b[j])
                   goto found;
       /* didn't find any common element */
       ...
   found:
       /* got one: a[i] == b[j] */
       ...
Code involving a goto can always be written without one, though perhaps at the price of some repeated tests or an extra variable. For example, the array search becomes 

   found = 0;
   for (i = 0; i < n && !found; i++)
       for (j = 0; j < m && !found; j++)
           if (a[i] == b[j])
               found = 1;
   if (found)
       /* got one: a[i-1] == b[j-1] */
       ...
   else
       /* didn't find any common element */
       ...
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. 



Using GOTO in your software is a widely debated issue. What are your thoughts?

Sat Nov 07 2009, 03:06 PM
#2
I believe if you know what you are doing then its not a problem using goto statement. I sometimes really feel difficult to understand why people abuse so much?

If goto can make you life simple then why not use it? I am not a master in programming but i feel wherever you can use goto just use it.

I have seen uIP 0.9 implementation by Adam Dunkels, he made a heavy use of goto statement just to make things simpler, he could also use switch case statements but he decided to use goto.

Can anyone points to problem that can arise using goto?
Sat Nov 14 2009, 04:17 AM
#3
Searching the web, I ran across a very good description of when to use goto...

The author wrote:

When To Use Goto When Programming in C
Although the use of goto is almost always bad programming practice (surely you can find a better way of doing XYZ), there are times when it really isn't a bad choice. Some might even argue that, when it is useful, it's the best choice.

Most of what I have to say about goto really only applies to C. If you're using C++, there's no sound reason to use goto in place of exceptions. In C, however, you don't have the power of an exception handling mechanism, so if you want to separate out error handling from the rest of your program logic, and you want to avoid rewriting clean up code multiple times throughout your code, then goto can be a good choice.

What do I mean? You might have some code that looks like this:

int big_function()
{
    /* do some work */
    if([error])
    {
        /* clean up*/
        return [error];
    }
    /* do some more work */
    if([error])
    {
        /* clean up*/
        return [error];
    }
    /* do some more work */
    if([error])
    {
        /* clean up*/
        return [error];
    }
    /* do some more work */
    if([error])
    {
        /* clean up*/
        return [error];
    }
    /* clean up*/
    return [success];
}

This is fine until you realize that you need to change your cleanup code. Then you have to go through and make 4 changes. Now, you might decide that you can just encapsulate all of the cleanup into a single function; that's not a bad idea. But it does mean that you'll need to be careful with pointers -- if you plan to free a pointer in your cleanup function, there's no way to set it to then point to NULL unless you pass in a pointer to a pointer. In a lot of cases, you won't be using that pointer again anyway, so that may not be a major concern. On the other hand, if you add in a new pointer, file handle, or other thing that needs cleanup, then you'll need to change your cleanup function again; and then you'll need to change the arguments to that function.

In some cases, this might be acceptable -- but if you're making a lot of changes to your code, adding in new variables, etc. -- it may not be worth the time or the extra lines of code to make that function call.

Instead, since you know that you're going to be executing only one piece of code and then returning from the function, you might as well use a goto to jump to the very end of the function, where you have your cleanup code.

Goto is a pretty simple keyword: you just need to include a "label" placed above the target location (followed by a colon), and then direct the program to go to the label. Note that this only works within the same function; you can't just enter one function from another.

goto label;
/* Code
...
*/
label:

Now, using this, if we want to handle all our errors in one place, we'll need to add in a variable to track the return value of our function so we can return it:

int big_function()
{
    int ret_val = [success];
    /* do some work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    /* clean up*/
    return ret_val;
}

The benefit here is that your code following end has access to everything it will need to perform cleanup, and you've managed to reduce the number of change points considerably. Another benefit is that you've gone from having multiple exit points for your function to just one; there's no chance you'll accidentally return from the function without cleaning up.

Moreover, since goto is only being used to jump to a single point, it's not as though you're creating a mass of spaghetti code jumping back and forth in an attempt to simulate function calls. Rather, goto actually helps write more structured code.

There is one thing to be aware of: while your cleanup code should be able to free all of the memory you use, there may be times when you actually want to free that memory yourself and possibly reallocate it later. In these cases, if you do call free on a ptr and then have an if([error]) between that call to free and the subsequent call to malloc, you should definitely set the pointer to point to NULL! This will prevent your jumping to the cleanup code and then calling free on that pointer a second time, which can result in a security hole (the "double free" problem).

Goto should always be used sparingly, and as a last resort -- but there is a time and a place for it. The question should be not "do you have to use it" but "is it the best choice" to use it.



The website is here: http://www.cprogramming.com/tutorial/goto.html


[ Edited Sat Nov 14 2009, 04:19 AM ]
 ajay_bhargav like this.
Sat Nov 14 2009, 11:08 AM
#4
That explains a lot
I really like this method of spreading and gathering good knowledge
Mon Nov 16 2009, 03:19 PM
#5


I believe if you know what you are doing then its not a problem using goto statement. I sometimes really feel difficult to understand why people abuse so much?

If goto can make you life simple then why not use it? I am not a master in programming but i feel wherever you can use goto just use it.

I have seen uIP 0.9 implementation by Adam Dunkels, he made a heavy use of goto statement just to make things simpler, he could also use switch case statements but he decided to use goto.

Can anyone points to problem that can arise using goto?

Ajay Bhargav



The goto statement has run me into alot of problems when I started coding in embedded C. I sometimes find that using goto before closing a while(1) loop can cause 18F series PIC chips to crash. Goto can be used to make things much simpler but I personally think it is down to the programmer. While working on projects in different teams, I find that some programmers code in a style that is similar to the language they started out with.

I've noticed one guy who started out coding in assembly, his C code looks very similar in structure!
Mon Nov 16 2009, 07:39 PM
#6
banked memories may cause a problem with goto i believe. 8051 is fairly simple architecture where you can jump from anywhere in range of 64K. So architectures also play big role on how you code.

but most of time Its on user how he use it or code it.
Mon Nov 16 2009, 09:52 PM
#7


The goto statement has run me into alot of problems when I started coding in embedded C. I sometimes find that using goto before closing a while(1) loop can cause 18F series PIC chips to crash.

Retellect


I suspect that the compiler may be careless as to how it codes while loops.
Useful warning though.


[ Edited Mon Nov 16 2009, 09:53 PM ]

Get Social

Information

Powered by e107 Forum System

Conversation

Wed Dec 11 2019, 07:59 AM
Sarah Gold
I was recently on your site and I can see you continue to pour time and energy into your digital presence. Your hard work shows and it’s really coming along!
Thu Nov 21 2019, 12:30 PM
raj2555
how to interface 8051 microcontroller with NRF24L01+ module
ExperimenterUK
Sat Oct 12 2019, 10:23 PM
Log in.. then post your code in the 8051 forum
Sat Oct 12 2019, 10:18 AM
Bhadra Sajikumar
i am doing a countdown timer with 8051 for my project, unfortunately our professor had to take a leave of absence before he could teach us most of it.. can someone explain the .asm code of it for me?
Mon Sep 23 2019, 07:37 AM
Nathaniel
I am doing a project for my schools wireless security system with cameras,sensors and spot lights using 8051 micro controller, could you help me out with the design and its source code.
Wed Sep 18 2019, 08:48 PM
Caryn Kover
Thank you for your time,
ExperimenterUK
Mon Aug 05 2019, 07:09 PM
@Ismail ..post in forum, give details
Mon Aug 05 2019, 04:33 PM
Ismail balghmi
Hello. Please I won't download
ExperimenterUK
Wed Jul 24 2019, 12:47 AM
@BUSTER123 Please post in the forum
Tue Jul 23 2019, 06:13 PM
BUSTER123
hello! newbie here. i am kind of a guy who hates using ready - made existing libraries, so this helped a lot as i was trying to control and write to a character lcd display. however, i can't figure out how to set the cursor position. for example, i want to set it to the 5th column in the first row, so position 5. so according to the table, i am sending 10000101 on the 8 data lines of the lcd (register select pulled low). the cursor does not move there however. and i cant move the cursor left or right too. is it something wrong that i am doing? thank you.

Downloads

Comments

nabiha_anaya
Sun Dec 08 2019, 09:16 AM
ananyagupta
Tue Dec 03 2019, 07:53 AM
wells
Mon Nov 25 2019, 08:25 PM
auwal
Tue Nov 19 2019, 03:13 PM
ANKITPATEL
Mon Nov 18 2019, 11:00 AM
Casmir
Wed Nov 13 2019, 06:25 AM
DeepakBGattani
Mon Nov 11 2019, 01:31 PM
Jeanbusatta
Sun Nov 10 2019, 04:42 AM

Online

Guests: 56, Members: 0 ...

most ever online: 182184
(Members: , Guests: 182184) on 06 Aug 2010: 05:37 AM

Members: 38108
Newest member: nabiha_anaya
Forum Activity
ExperimenterUK Avatar
Posted By ExperimenterUK
Tue Dec 10 2019, 04:49 PM
ilylily07 Avatar
Posted By ilylily07
Sun Dec 08 2019, 01:24 PM
Hi .im humbly ask for your advice as i wrongly pur...
nabiha_anaya Avatar
Posted By nabiha_anaya
Sun Dec 08 2019, 09:19 AM
My teacher assign me a project on "voice control h...
ExperimenterUK Avatar
Posted By ExperimenterUK
Fri Nov 29 2019, 04:24 AM
" Is it possible to interface a fingerprint scanne...
ilylily07 Avatar
Posted By ilylily07
Thu Nov 28 2019, 03:50 PM
You will not find any code for an 8051 as no one w...
ExperimenterUK Avatar
Posted By ExperimenterUK
Tue Nov 26 2019, 05:44 PM
You will not find any code for an 8051 as no one w...
ilylily07 Avatar
Posted By ilylily07
Tue Nov 26 2019, 04:13 AM
I tracked down a OV7670 data sheet.The OV7670 puts...
ExperimenterUK Avatar
Posted By ExperimenterUK
Tue Nov 26 2019, 12:08 AM
I tracked down a OV7670 data sheet.The OV7670 puts...
ilylily07 Avatar
Posted By ilylily07
Mon Nov 25 2019, 04:38 PM
The 8051 has too little memory to do anything us...
ExperimenterUK Avatar
Posted By ExperimenterUK
Tue Nov 19 2019, 10:44 PM
The 8051 has too little memory to do anything us...