- #1
- 8,855
- 632
Rather than hijack the help with C thread, discussion can continue here.
On a somewhat related issue, I prefer to use pointer to functions as opposed to state variables (switch case) for deferred actions, as it allows a series of small functions to be sequentially located in a source file rather than tied into the switch case statement for some common message handler. If I need to add a step, I don't have to edit the common message handler as it just calls a pointer to function. C++ implements the equivalent in it's classes, for C, structures can have pointers to functions.
Jeff Reid said:I don't understand why most programmers are "anti-goto". It's far easier to search for a label than a trailing right brace. Regardless of how you write your C code, eventually the assembly equivalent of a "goto", a branch or jump instruction is going to be used (except machines that have conditional execution of instructions such as the Motorola 68000 series, and it only helps with 2 to 4 instruction sequences). If there are multiple entry or exit points in a program's loops, then goto's are OK.
mXSCNT said:The main problem with goto is that it can do almost anything. When reading code, it's harder to figure out what a goto or label is for than what a loop is for, because the goto could do so many things (jumping control to anywhere in the program). A loop can only apply to the loop body, and two loops can't "overlap" the way gotos can. That means it is easier to reason about loops than gotos, so loops are preferable when possible.
AUMathTutor said:"I don't understand why most programmers are "anti-goto"."
For high-level programming, they are generally considered too unstructured. They support ad-hoc programming and decrease readability.
"It's far easier to search for a label than a trailing right brace."
I disagree. With proper use of white space, C-style brace notation makes it very easy to see the block-structure.
"Regardless of how you write your C code, eventually the assembly equivalent of a "goto", a branch or jump instruction is going to be used (except machines that have conditional execution of instructions such as the Motorola 68000 series, and it only helps with 2 to 4 instruction sequences)."
What do you mean here? Yes, whenever code is translated into assembly language, loops and conditionals become the equivalent of "goto".
But any and all programs require only a single while loop and the if-then-else structure. This is provably true.
"If there are multiple entry or exit points in a program's loops, then goto's are OK."
I respectfully disagree. If your code starts using several goto's, you probably need to rework your design.
Just like anything else, goto's can be used appropriately or inappropriately. Inappropriate use doesn't invalidate using goto's.AUMathTutor said:"I don't understand why most programmers are "anti-goto"."
For high-level programming, they are generally considered too unstructured. They support ad-hoc programming and decrease readability.
Jeff Reid said:"It's far easier to search for a label than a trailing right brace."
"I disagree. With proper use of white space, C-style brace notation makes it very easy to see the block-structure."
Take this sequence
Code:// step 1 if(status_from_step_1 == OK){ // step 2 if(status_from_step_2 == OK){ // step 3 if(status_from_step_3 == OK){ // step 4 } } } }
versus:
Code:// step 1 if(status_from_step_1 != OK) goto exit0; // step 2 if(status_from_step_2 != OK) goto exit0; // step 3 if(status_from_step_3 != OK) goto exit0; // step 4 exit0: // common exit point
The first sequence involved uneeded indention, and implication that step3 is a sub-step of step 2 which is a sub-step of step 1, when they are really at the same level. IMO, it's a lot easier to find exit0 than to find that right brace, especially if the indentation is messed up.
I assume you mean one main loop per function, not per program. Take the case of a file copy or backup program that processes all the files in a directory before working on any subdirectories. There are two main loops, one to process all files in the current directory, and one to process all the sub-directories, recursively calling the process files loop, which in turn recursively calls the process sub-directories loop, ...But any and all programs require only a single while loop and the if-then-else structure. This is provably true.
On a somewhat related issue, I prefer to use pointer to functions as opposed to state variables (switch case) for deferred actions, as it allows a series of small functions to be sequentially located in a source file rather than tied into the switch case statement for some common message handler. If I need to add a step, I don't have to edit the common message handler as it just calls a pointer to function. C++ implements the equivalent in it's classes, for C, structures can have pointers to functions.
AUMathTutor said:"Just like anything else, goto's can be used appropriately or inappropriately. Inappropriate use doesn't invalidate using goto's."
Fair enough. I like to avoid them, however, because I feel it's all too easy to misuse them. I guess when it comes to the GOTO I prefer to err on the side of not using them.
"The first sequence involved uneeded indention, and implication that step3 is a sub-step of step 2 which is a sub-step of step 1, when they are really at the same level. IMO, it's a lot easier to find exit0 than to find that right brace, especially if the indentation is messed up."
I disagree. Fundamentally, the subsequent if statements do depend on each other. This dependence is explicit. I think the indentation should be preferred because it illustrates this fact. It's only if you think in terms of the GOTO that it seems that those steps are on the same level... they're not.
"I assume you mean one main loop per function, not per program."
False. I suggest you read the proof of Boehm and Jacopini. Any algorithm which can be described using a flowgraph can be written using a single while loop and if-then-else structures. Any recursive algorithm can be written as an iterative algorithm... so recursive functions aren't exempt from Boehm-Jacopini.
"On a somewhat related issue, I prefer to use pointer to functions as opposed to state variables (switch case) for deferred actions, as it allows a series of small functions to be sequentially located in a source file rather than tied into the switch case statement for some common message handler. If I need to add a step, I don't have to edit the common message handler as it just calls a pointer to function. C++ implements the equivalent in it's classes, for C, structures can have pointers to functions."
...
Last edited: