You say it's not superstition, but you don't mention a reason for avoiding gotos!
Ok, my main point: when you use the natural devices to give your code structure, they provide you with explicit clues that help you read the structure. Indent notwithstanding (because you could easily indent your goto-laden code manually), when you see a "{" or a "BEGIN" (Pascal), a "END" or a "}", you instantly understand where to look for the body of code that interests you. When you implement structure with "goto", just looking at that line gives you nothing (though, yes, the name of the label might help, but label naming conventions must be implemented by the coder). Avoiding goto gives your code a clear and consistent structure and, if you are hard-nosed, forces you into consistent programming patterns. In addition, the lack of illuminating label names encourages you to comment your code more thoroughly (if you want to be able to maintain it).
Now, take a look at the code in the OP:
Code:
#include <stdio.h>
main ()
{
int remainder, numerator, denominator ;
printf ("This program computes the remainder of user entered numbers," ) ;
printf ("0 to exit\n") ;
do {
printf ("Enter a number: ") ;
scanf ("%d", &numerator) ;
if (numerator == 0) goto done;
printf ("Enter a number: ") ;
scanf ("%d", &denominator) ;
remainder = numerator % denominator ;
printf ("%d\n", remainder) ;
} while (numerator != 0);
[B][COLOR="Red"]done[/COLOR][/B]: printf ("Thank you, have a nice day\n") ;
return 0;
}
Note the location of the exit label. Now, when I see a piece of structure like a loop, I see that it ends with the "}", and (apart from the trailing "while" clause in this example) there is nothing after that. Hence, if I want to insert code after the loop, I will instinctively add it
before the "
done:" label, which is rather obviously not where such an insertion should be made.
In other words, you could easily design and structure any fully-functional program completely out of gotos and labels ("if" would be the only other flow control), though I suspect it would probably be a major PITA to debug to workable and then subsequently maintain. Alternately, you could completely eschew the goto concept and rely entirely on the language's natural structural components, in which case the code would almost certainly be easier to read and maintain. As shown in the example above, mixing goto with natural structure is dangerous and confusing practice. There may in fact be times when you really do need to do that, but if it comes to that, the routine in question ought to be 10% lines-of-code and 90% //documentation, just to be on the safe side.
(
Personally, I do not even like to have more than one return statement in a routine.)