I will concern myself mostly with goto, but first a little on flow charts.
##On Flow charts I see flow charts as just a ways to visually represent goto-ful low-level algorithms/code. Some other answers have mixed up their use with state-machines, or decision trees. Doing this could result in program-size complexity, for a sorting algorithm, of $O(n!)$ where the execution complexity could be only $O(n\log{n})$.
###Good uses of flow charts The low-level nature of flowcharts can be of great value, when creating a procedure to be carried out by humans. I.e. A first aid flowchart.
##On goto statement and goto In the paper “Go To Statement Considered Harmful”, Dijkstra is concerned with the goto statement, not with goto. He points out that all higher order structures will use goto in their implementation. According to Dijkstra, this implementation is not the problem, only the direct use of goto. In the time since his paper the structure he mentions, if, else, while, for, until, repeat, and sub-routines have been part of our high-level languages. For his call was not for us to stop using it in programs, but to create languages that did not require it, and then to stop using it. And in the meantime to use it only in a structured way, to simulate the structures. Therefore only use it if your language does not provide the high-level structure that you need, and know which structure you are simulating (don't ad-hok it).
For a number of years I have been familiar with the observation that the quality of programmers is a decreasing function of the density of go to statements in the programs they produce. More recently I discovered why the use of the go to statement has such disastrous effects, and I became convinced that the go to statement should be abolished from all "higher level" programming languages (i.e. everything except, perhaps, plain machine code). At that time I did not attach too much importance to this discovery; I now submit my considerations for publication because in very recent discussions in which the subject turned up, I have been urged to do so. (Edsger Dijkstra)
###Good uses of goto statement
- Programming in assembler, though you should not have much assembler language in your project.
- Compilers/generators: These will use
gototo create higher-level structures. - To over come limitations of the language, but consider changing language: In
Cyou may usegototo implement exception handling. However ensure that you have a clear idea of the structures that you are implementing. Do not usegotoin an ad-hoc way.
###When goto can seem like a good idea. goto is easy to understand, how it does it. However the code that you create (beyond the most trivial) is not easy to understand what it does.
My second remark is that our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed. For that reason we should do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap between the static program and the dynamic process, to make the correspondence between the program (spread out in text space) and the process (spread out in time) as trivial as possible.
That is our attempts to understand a large system, in terms of how it works in a dynamic way, are going to be very limited. However it is possible to view the system in a static way, and thus make it easier for our brains to comprehend. To do this we must let go of a little of the how. We do not seem to have a problem with this in most cases: we care not how print is implemented.
###On assembler code and machines So our CPUs use goto (jmp instructions). So what, unless you are teaching assembler language and CPUs.
But do all CPUs use goto? Possibly not, I am not an expert on this. However here is a discussion on what modern CPUs think of goto/jmp.
That happens when a modern (instruction pipelined cpu), fetches a conditional jump instruction?
All is not well, first it tries to guess which way the branch will go, then it goes that way. If it get it wrong it hits the brakes, backs up and tries again. The circuitry in the x86 for making this guess, is huge. The x86 does not like goto. What about the ARM, its branch prediction circuit is tiny (if it is a branch back, then assume that the branch will be taken, else assume that it will not), The ARM is better at predicting branches than the x86, but how? The arm has more conditional instructions, that is, it has selection built in. This allows it to avoid goto a lot of the time. Its simplistic algorithm then assumes that a jump backward is a loop, and a jump forward is a selection. So though iteration is not explicitly encoded, and selection is only sometimes explicitly encoded. This shows that knowledge of the programs structure is not just a high level thing, it can help the CPU's performance.
##Conclusion Only teach goto, when teaching assembler language, or at a late stage in high-level programming. However first teach the higher level structures, and make it clear that goto is only a work around for lack of higher-level structures in the language.