Other Languages - c++ programming - Asked By Najeeb Ullah on 22-Nov-11 09:54 AM

short Answer with example
why it prohibited to go to statement.
Suchit shah replied to Najeeb Ullah on 22-Nov-11 02:06 PM
The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one's program. One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs
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:

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.
Jitendra Faye replied to Najeeb Ullah on 22-Nov-11 11:32 PM
Goto Statement

The goto statement simply moves the flow of control over to some label. e.g.

...
Hello:
...
goto Hello
...

Goto will execute an unconditional jump to the destination. In order to place a condition on the jump it could be wrapped inside an if statement.


Disadvantages of Goto

Goto should not really be used in programs at all. They have a tendancy to make code unstructured and they make programs difficult to manage when they become significantly large.


It is much better practice to use the other flow control constructs and procedures.


you should avoid goto as much as you can.use only when using in large nested programs. otherwise use of goto makes the program unreliable,unreadable,and hard to debug.

one more big problem with goto is that when we do use them we can never be sure how we got to certain point in our code.they obscure the flow of control. so avoid them.

Reena Jain replied to Najeeb Ullah on 23-Nov-11 12:45 AM
HI,

I've never had to use a goto in C++. Ever. EVER. If there is a situation it should be used, it's incredibly rare. If you are actually considering making goto a standard part of your logic, something has flown off the tracks.

There are basically two points people are making in regards to gotos and your code:
1. Goto is bad. It's very rare to encounter a place where you need gotos, but I wouldn't suggest striking it completely. Though C++ has smart enough control flow to make goto rarely appropriate.
2. Your mechanism for cleanup is wrong: This point is far more important. In C, using memory management on your own is not only OK but often the best way to do things. In C++, your goal should be to avoid memory management as much as possible. You should avoid memory management as much as possible. Let the compiler do it for you. Rather than using new, just declare variables. The only time you'll really need memory management is when you don't know the size of your data in advance. Even then, you should try to just use some of the STL collections instead.

In the event that you legitimately need memory management (you have not really provided any evidence of this), then you should encapsulate your memory management within a class via constructors to allocate memory and deconstructors to deallocate memory.

Your response that your way of doing things is much easier is not really true in the long run. Firstly, once you get a strong feel for C++ making such constructors will be 2nd nature. Personally, I find using constructors easier than using cleanup code, since I have no need to pay careful attention to make sure I am deallocating properly. Instead, I can just let the object leave scope and the language handles it for me. Also, maintaining them is MUCH easier than maintaining a cleanup section and much less prone to problems.

In short, goto may be a good choice in some situations but not in this one. Here it's just short term laziness.