Sign in to follow this  

Recommended Posts

Sometimes..
C has got about a dozen different control structures each useful in various situations, I suggest you try to get comfortable with all of them.

[Edited by - doynax on June 3, 2005 9:04:36 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by aleksi1578
Well I program in C++/C.. Please can you tell some other ways than goto? or any tutorials that has some of them/all of them?
The function call is the basic method in C.
Try to find some introductory C book or equivalent online tutorials. A trip to your local library might not be a bad idea.

Share this post


Link to post
Share on other sites
You should not use goto instruction, as it is deprecated and shows bad coding habbits. Instead, you need to learn how to use loops [do, do-while, while, for], function calls and exception handling [the latter is C++ only, and rather an advanced topic].

As Doynax said, try to find a good C / C++ book or online tutorial and code as much as you can ;)

Share this post


Link to post
Share on other sites
That I can think of, gotos are never necessary in C++. And if I remember correctly, they don't obey scoping rules either. For example:

void SomeFunc()
{
int i = 0;
while (true)
{
std::string s('!', 1024);
++i;
if (i == 1)
{
goto end_of_func;
}
}
end_of_func:
}


I'm pretty sure that the std::string object won't get properly destructed, since it never officially goes out of scope. This is bad.

What specifically are you trying to accomplish, because I'm confident that it can be rewritten or redesigned slightly to not use gotos.

Share this post


Link to post
Share on other sites
It's a bit better [luckily] :). As far as I know, with goto you cannot leave or enter a block, so:

void SomeFunc()
{
int i = 0;
goto inside_loop; //error, cannot enter block
while (true)
{
inside_loop:
std::string s('!', 1024);
++i;
if (i == 1)
{
goto end_of_func; //error, cannot leave block
}
}
end_of_func:
goto end_of_func; //ok, now it is valid -> infinite loop ^^
}


As I said, I'm not 100% sure about it since I never use goto ;), but as far as I recall the label must be in the same block that the goto statement, not inside a subblock or superior block of code.

Share this post


Link to post
Share on other sites
Quote:
Original post by TeMPOraL
It's a bit better [luckily] :). As far as I know, with goto you cannot leave or enter a block, so:
*** Source Snippet Removed ***
As I said, I'm not 100% sure about it since I never use goto ;), but as far as I recall the label must be in the same block that the goto statement, not inside a subblock or superior block of code.



In C/C++, goto can be used to jump to any label within the same function. However, this is virtually always unwise, for reasons which have already been mentioned.

Share this post


Link to post
Share on other sites
Quote:
Original post by TeMPOraL
You should not use goto instruction, as it is deprecated

Deprecated in what way? The standard doesn't say it's deprecated.

Anyhoo, I've never needed to use a goto.

Share this post


Link to post
Share on other sites
TeMPOraL - goto is deprecated? Thank for telling me. </sarcasm> Bad style? Depends on whom you listen to.
Agony - C++ gotos do respect scope. Furthermore, you can only jump out of scopes, not into, nor across functions.

If a goto simplifies your code, by all means, use one! If it does not, do not.

Share this post


Link to post
Share on other sites
petewood:
Well... deprecated not in the official way, but rather using it is a bad coding habit and everybody knows that ;). It's a remnant from linear style of programming.

ApochPiQ:
My error; but still, this should not encourage us to use goto ;).

Share this post


Link to post
Share on other sites
umm this is intresting. I haven't read the whole thread but I have recently come across a situation where I could not immediately think of a simple way round the goto, that is in a nested loop:



while(true)
{
if(condition)
{
break; // thats fine can get to the end of loop
}
}

// but when in two loops and want to leave both if some exception in inside
// loop only goto works I believe

while(true)
{
while(true)
{
if(condition)
{
// break will only leave this function
goto label;
}
}
label:
}


wondering if there is a better way round this. Without having to make ridclous amount of functions i.e. put code at end of loop in another function then call that function when condition hit and return

Share this post


Link to post
Share on other sites
I recall you could do 'break label' instead of 'goto label' which then would circumvent the issues that were mentioned earlier in this thread.

EDIT: Kernighan & Ritchie just use goto in their example.. Break using a label seems to be a Java-only feature [shame]

Share this post


Link to post
Share on other sites
Quote:
Original post by WizHarDx
umm this is intresting. I haven't read the whole thread but I have recently come across a situation where I could not immediately think of a simple way round the goto, that is in a nested loop:

[code snippet removed]

wondering if there is a better way round this. Without having to make ridclous amount of functions i.e. put code at end of loop in another function then call that function when condition hit and return


Well, but your latter code does not leave the loop ;). In that case I'd either use an boolean value and if statement in outer loop, or throw an exception from the inner loop and catch it outside of the loops. I'd also try to move those two loops into one function, so I could use return to leave them. I think that this situation can be avoided if code is properly designed ;).

Share this post


Link to post
Share on other sites
Quote:
Original post by WanMaster
What language? In general, I would advice against it, unless you have no choice (like in old fashioned Basic).


Goto is a tool. Use it when the problem requires it. I've seen a lot of bad code written just to avoid using a goto.

Quote:
Original post by TeMPOraL
petewood:
Well... deprecated not in the official way, but rather using it is a bad coding habit and everybody knows that ;). It's a remnant from linear style of programming.

ApochPiQ:
My error; but still, this should not encourage us to use goto ;).


Goto is not a remnant of linear style programming. Exception handling was a big reason to use goto in the past, which is of course now can be done with structured exception handling. However there are situations where a goto is the best tool for for the job.

Share this post


Link to post
Share on other sites
Quote:
Original post by DaBono
I recall you could do 'break label' instead of 'goto label' which then would circumvent the issues that were mentioned earlier in this thread.

EDIT: Kernighan & Ritchie just use goto in their example.. Break using a label seems to be a Java-only feature [shame]


So then what would be the difference between using "break [label]" and "goto [label]"? None. Exactly the same result is being accomplished in exactly the same way. It simply doesn't trigger people's unreasonable bias against the goto statement.

Share this post


Link to post
Share on other sites
RunUO serialize and deserialize function use the goto feature to save some information about objets. It's pretty neat, and a good way to do that. Goto can usefull. Many people say it's the devil since they heard that from someone else... But it's bullshit.

Share this post


Link to post
Share on other sites
I'd say, the C++ ish answer is:

- Don't use goto

and the C answer is

- Don't use goto except for a very special case, where you need to jump to your uninitialisation code inside a function in an error case

The latter, is commonly used in Linux* for error paths in system call functions. This is vaguely justified because:

- They frequently have a lot of allocation / deallocation code
- They can't use C++ (There are a lot of arguments one way and the other, but NO, Linux is not, and cannot be written in C++) (Windows kernel is not written in C++ either, but some parts of Macos X are)
- They are generally extremely accomplished coders and usually manage to do this correctly.

Mark

* Linux is of course, a kernel not an operating system. Many other system software components found running on GNU/Linux systems are written in C++.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by TeMPOraL
Quote:
Original post by WizHarDx
umm this is intresting. I haven't read the whole thread but I have recently come across a situation where I could not immediately think of a simple way round the goto, that is in a nested loop:

[code snippet removed]

wondering if there is a better way round this. Without having to make ridclous amount of functions i.e. put code at end of loop in another function then call that function when condition hit and return


Well, but your latter code does not leave the loop ;). In that case I'd either use an boolean value and if statement in outer loop, or throw an exception from the inner loop and catch it outside of the loops. I'd also try to move those two loops into one function, so I could use return to leave them. I think that this situation can be avoided if code is properly designed ;).


Assuming that the latter code was meant to leave the loop:
- I find the boolean value solution less readable. Invariably the variable is named something like "finished" which, while true, is not very descriptive of what's finished. Reminds me of commented code like:

int a; // Integer variable named a

- Using exceptions is something like hunting bunnies with nukes. Sure, you got the bunny, but did you really need that much fire power? Plus, exceptions can be expensive.

- Factoring it into another function is all well and good if such a factorization makes sense, but it usually doesn't in my experience. If C or C++ allowed anonymous or nested functions, then I'd say this is the best solution. As it is, it's more trouble than it's worth.

- The worst goto's are goto's that jump backwards. Make it a general rule that all goto's jump forwards and you eliminate 99% of goto headaches. Now all you're left with is finding the label. Assuming a good coder, the code should be readable and this won't be a problem. Assuming a bad coder, press Ctrl+f or equivalent and your problem is solved. (If a goto does jump backwards, comment it well).

Share this post


Link to post
Share on other sites
Some interesting experimentation:

class CVictim
{
int m_ID;

public:
CVictim(int ID)
: m_ID(ID)
{
cout << "Constructed victim " << ID << endl;
}

~CVictim()
{
cout << "Destructed victim " << m_ID << endl;
}
};


void AbuseGoto()
{
int i;
CVictim a(999);

goto horrible;

for(i = 0; i < 15; ++i)
{
horrible:

CVictim b(i);

switch(i)
{
case 2:
++i;
goto horrible;
case 6:
goto abuse;
default:
break;
}
}

cout << 0xdeadc0de << endl;

abuse:
cout << "End of Abuse" << endl;
}



This compiles cleanly in VC++6 (which, of course, does not necessarily mean it is valid). The initial "goto horrible;" creates undefined behavior. Removing it produces the following output:

Constructed victim 999
Constructed victim 0
Destructed victim 0
Constructed victim 1
Destructed victim 1
Constructed victim 2
Destructed victim 2
Constructed victim 3
Destructed victim 3
Constructed victim 4
Destructed victim 4
Constructed victim 5
Destructed victim 5
Constructed victim 6
Destructed victim 6
End of Abuse
Destructed victim 999


So all of the objects are properly destructed.


Behavior may vary with a better compiler.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
- The worst goto's are goto's that jump backwards. Make it a general rule that all goto's jump forwards and you eliminate 99% of goto headaches.


Very good point. In most situations, if you need to jump backwards then you could be using a loop.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
TeMPOraL - goto is deprecated? Thank for telling me. </sarcasm> Bad style? Depends on whom you listen to.
Agony - C++ gotos do respect scope. Furthermore, you can only jump out of scopes, not into, nor across functions.

If a goto simplifies your code, by all means, use one! If it does not, do not.


Problem is it doesn't simplify your code. It makes it impossible to follow the code flow (Yes, looking at a goto statement, and then skipping to whatever it points to is easy enough, but the other way is impossible. Just about any point in the code could be the destination of a goto, and you have no way of finding this out.

For this reason alone, try to avoid goto. True, the alternatives aren't always pretty either, but at least they let you see the code paths no matter where in the code you look. You always know where a loop jumps to, and looking at a code section, you can always recognize it if it's something that can be jumped to with if, else, for or while. With a goto, you can't. It might jump to just that line, or it might not, You have no way of finding out, other than searching for every goto in your program.

Of course, you might want to use a goto despite all of this, but keep it in mind, at least. If you're forced to use a goto, at least make sure it doesn't turn into too much spaghetti code. Make sure it's easy to see all the code paths. Make sure that it's easy to see, when you're looking at a line of code, whether or not there's a goto leading to it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this