Re: “Goto statement considred harmful”
The problem is not there, but the goto requires a label as the target and that is where the problem lies.
A useful observation, but irrelevant to Dijkstra's critique. And it's not entirely true. Any statement that can cause premature exit from a basic block complicates program flow of control, both for determining things like data flow, and for a human reader studying the code. In C, that includes not just goto but break, continue, and return (which are just syntactic sugar for goto), and longjmp, which for this purpose behaves like goto optionally proceeded by a series of one or more returns. In languages and environments with exception handling, it includes exception handling.
A human reader studying a block that contains, or may contain, any goto-like construct has to consider premature termination of the block, which means the tail of the block may not be executed. It's easy to see the effect by converting the control-flow graph of a program with explicit gotos into a tree without them.
And people reading, and attempting to understand, source code accounts for around 40% of total software development costs, according to some estimates.
Personally, I like the judicious use of goto in C, particularly the "goto done" pattern to exit early but still perform end-of-function cleanup. (There are good alternatives, such as handling resources in an outer function; it's largely a matter of taste.) But that works precisely because it becomes an idiom and a reader can expect and recognize it.
Also, in languages like C, a label's scope is local to the function or procedure.
Labels are, yes, but then you have longjmp.
This is especially a problem in COBOL where there are section labels and paragraph labels and these may be dropped through, performed and performed thru, or be subject to a goto in various combinations.
By eliminating GO, PERFORM THRU, and SECTION labels the only constructs for accessing code out-of-line is the PERFORM and the CALL. This eliminates the complexity of determining the logic flow of the code, paragraph labels can be treated as if they were procedures (functions in C) with the only entry from a PERFORM and the return to that at the end of paragraph.
Unfortunately, not always true, due to the complex semantics of PERFORM in some conforming COBOL implementations. That's why we in fact recommend always putting PERFORMed code in a separate SECTION, rather than simply making it a paragraph - SECTION has stronger control-flow requirements. But yes, removing GO and PERFORM THRU from COBOL logic is felicitous, just like using the scope-terminating statements (END-IF et al).