“Dispute is possible where the truth is closed. In fruitless disputes, you can endlessly discuss that the room is a closed door. But it is worth opening the door, and it will become clear to everyone and there’s nothing to argue about, since every truth can see. ”
Vladimir Megre
The article is dedicated to Zatsepin PM, an outstanding engineer of the Altai State University, under whose strict guidance many students, including the author of the article, learned the magic of engineering creativity.')
Introduction
The argument about the possibility of using the GOTO operator in programs has been going on for a very long time (Dijkstra’s official recognition of the harm of the GOTO operator, published in 1968 [2]) was recognized as its beginning. In three years we will celebrate the 50th anniversary of this dispute. This is a good reason to finally "dot the i's" and stop the argument.
The quote in the epigraph was not chosen by chance. It accurately reflects the current situation in the GOTO dispute. In our case, the “room behind the closed door” is the formulation of the problem that everyone understands. So far, unfortunately, such a statement of the problem has not been voiced, therefore disputes do not fade. The opposing sides argue, though about similar, but still about different things, therefore, they cannot find a compromise.
Let's take a neutral side in this dispute, and let's deal with everything impartially. Consider the arguments of "opponents" and "defenders" of the operator GOTO and decide "which of them is right and who is to blame."
Why are disputes going on
As already noted above, disputes about the possibility of using the GOTO operator in programs are conducted because of the lack of a clear statement of the problem. Roughly speaking, one of the parties proves that the tree is floating, and the other that the brick is sinking. Naturally, with such a statement, each of the parties is sure that they are right and will always defend it.
Opponents GOTO rely on the rules of good form. It is here that the key to the "closed door" is hidden, since There are at least three good tone rules: “good tone in structuring,” “good tone in speed,” and “good tone in compactness,” but GOTO opponents take into account only one of them.
GOTO advocates rely on customer requirements, where, among others, items related to speed and compactness of the program are not uncommon. With such a statement, the rule of good tone cannot be avoided - you have to look for a compromise solution. As a result of such a solution, the GOTO operator sometimes appears in the program.
In this case, it is difficult to distinguish a brick from a log, since Recently, when developing programs, speed and compactness have received less and less attention. But this is not a reason for their complete disregard, since for any demand should be your offer.
The voiced point of view is very superficial, since does not take into account the details of the dispute. To formulate an objective statement of the problem, it is necessary to consider the arguments and counter arguments of each of the parties. This is what we will do now. The bold letters
H are the arguments of the GOTO defenders, and the bold letters
P are the arguments of the opponents of the GOTO.
The arguments of the "opponents" GOTO
1. Using GOTO - bad form.Z: This is not an argumentative statement, so there’s no point in arguing here.
2. The worst tone - back with a label back.Z: Indeed, GOTO cannot be used this way, just as it cannot be used to go to another block of the field of view - you can either stay in the current or go out of it. If you follow these two rules, you can use GOTO.
3. GOTO - redundant operator. It can easily be replaced by cycles and conditions.Z: For that matter, almost all operators can be thrown out of the language.
From the point of view of structured programming, all statements can be thrown out of the language altogether, leaving only while and the assignment operator. [1] In this case, the program will be at least voluminous, but understandable. If in practice attention was paid only to the structure of the program, then such a step would be reasonable, but in real problems there are also requirements for speed and compactness, and this cannot be achieved with a single operator.
GOTO is not a sign of the curvature of the code, but of the curvature of languages in which sometimes without it (C, C ++, C #, Pascal, Java, etc) and the curvature of profanation called “structural programming” with its so-called “Cycles with preconditions”, “cycles with postconditions” and “ramifications”, which are not elementary constructions, but typical patterns in which the task is not always conveniently placed.
The disadvantage is that if the task does not fall into these patterns ideally, then redundant code appears, which in some cases does not meet the requirements of compactness and speed.
4. Wirth and Dijkstra say that GOTO is bad. [2, 3]Z: Authoritative opinions are worthy of attention, but what the authorities say is not the ultimate truth. It is not without reason that the phrase “If a respected scientist says that“ it is possible to do it ”, then he is most likely right, and if he says that“ it is impossible to do it, ”then most likely is not right.
There are also such authorities that speak in favor of GOTO, for example, Donald Knut [4], Fredrik Brooks. [5] But in solving the problem it is more expedient to rely not on the opinion of authorities, but on common sense.
5. GOTO cancels many of the compiler's optimization capabilities of control structures, which makes the code slower and more complex. [2]Z: This problem is in no way related to GOTO, because optimization is performed at the level of machine codes. Yes, GOTO inserts a jump instruction into machine code that prevents code optimization, but the same instructions insert both a conditional statement and a loop statement.
The arguments of the "defenders" GOTO
1. Group of mutually exclusive conditions.Sample code ...if(objectA.nValue == objectB.nValue) { ... goto END; } if(objectC.nValue == objectD.nValue) { ... goto END; } if(objectE.nValue == objectF.nValue) { ... goto END; } END: ...
| if(objectA.nValue == objectB.nValue) { } else if(objectC.nValue == objectD.nValue) { } else if(objectE.nValue == objectF.nValue) { } … |
P: In this case, GOTO does not spoil the structure of the program, but in such a construction there is no practical need, since The same can be done through if / else.
Z: It is possible to replace the given code with if / else only if no additional operations are performed before completion.
P: Additional operations can be carried out in a separate function and called it in each branch.
Z: Taking out additional operations into a separate function will reduce the program speed, and in some cases this is unacceptable.
P: A separate function can be arranged in the form of an inline-function, then it will not affect the speed in any way.
Z: But then the program will take up more memory. And this, in some cases, may also contradict the task.
As a result of this dispute, completion procedures and a structural exception handling mechanism were introduced in many languages. These tools run a little slower than GOTO, but are more visual, so for most of the tasks they are quite enough. But, again, there are tasks where it is critical and this is “a bit” - in them the use of GOTO seems expedient.
2. The principle of universal causality - if somewhere there is a GOTO, then it is needed there.The new language does not appear from the bay-bash. The developers of programming languages have a difficult task - to satisfy all the requests of programmers, and take into account generally accepted paradigms. It is absurd to assume that a concept will be implemented in the language that no one needs. If we consider C as an example, then in general all questions disappear, since When analyzing the language, it seems that for each new operator introduced into the language, the developers had to pay $ 5000 out of their pocket ... and the GOTO operator is there.
3. Exit from multiple cycles simultaneously.P: Classic argument. You can not argue against him.
4. State machines (sample code). state_1: switch (signal) { case 1: goto state_5; case 2: goto state_10; case 3: goto state_8; } state_2: switch (signal) { case 7: goto state_37; case 10: goto state_1; case 9: goto state_100; } | |
5. Another example.Sample code ... for (int i=0;i<n1;++i) { for(int j=0;j<n2;++j) { if(come_condition1) goto next1; for(int k=0;k<n3;++k) { if(come_condition2) goto next2; } | inline void doSomeActivityInFor() { for(int i=0;i<n1;++i) { for(int j=0;j<n2;++j) { if(come_condition1) return; if (some_condition3(i,j) { break; } // some code } // some code } inline bool some_condition3(i,j) { for(int k=0;k<n3;++k) { if(come_condition2()) return true; } return false; } |
P: The code above is executed at the same speed and takes up as much memory as the code with GOTO.
Z: This example once again shows that you need to take a closer look at the development of the algorithm. Using GOTO in programs is permissible, but it is not necessary to rush from one extreme to the other.
Let's sum up
Crowds of religious fanatics of a team of qualified programmers often abandon the GOTO operator, even when its use is expedient from the point of view of program efficiency and visibility.
Bad pitch in programming? If only the “structuring tone” is taken into account, then yes. But there is still a "tone of speed" and "tone of compactness," so you need to find a compromise between them. [6] Programmers "working in the sandbox", as a rule, solve problems that do not have to think about saving resources, hence the misunderstanding.
Ignoring the “structuring tone” is also impossible, since In any case, the program will have to be finalized, and if there is an intricate structure in it, then unnecessary costs will arise. As with any other practical solution, the best compromise is the use of GOTO, but with the following reservations:
- You can only go forward.
- It’s absolutely impossible to enter the blocks (either stay or go out).
Most likely, stories about the harmfulness of the GOTO operator are invented for novice programmers, so that they do not use it during training. Students studying structural programming and language constructions in universities know that GOTO is evil. But when a specific task arises, it is necessary to proceed from it, and not from the templates provided by the programming language. It rarely happens that a concrete pattern corresponds to a practical task. GOTO just helps to adapt existing templates to the task being solved.
Thanks
I am grateful to the people who shared with me the information and their thoughts about the justification for using the GOTO operator in the programs. Without your help, the article would express the one-sided opinion of a single person, i.e. me. Together with you, we were able to support a constructive dispute, which resulted in a clear answer to the topic of concern to a large number of programmers.
Who are these people? Here they are:I thank Dmitry Leonov for creating the site bugtraq.ru and for the fact that he managed to rally a large number of high-class specialists in his forum. It was at this forum that the most interesting discussion took place. I thank the people who took part in the discussion on this forum:
Thanks to OlegY, Heller, Zef for code examples where using GOTO is justified.
I thank HandleX for philosophical thoughts about the necessity of GOTO in solving practical, not theoretical problems.
Thanks to amirul for voicing the GOTO application rules.
Thanks to AMMOmium for the thought of “horror stories” for novice programmers.
I thank the team of programmers from the codenet.ru forum for an illustrative example of a classic dispute, namely the following persons: nilbog, koderAlex, OlgaKr, kerdan, kosfiz3A3-968M, IL84, fanto, Sanila_san, nixus, green, newonder.
Ps. Thanks for attention. I would welcome comments; Questions and objections are also welcome.
Bibliography
- R. Linger, H. Mills, B. Witt. Theory and practice of structured programming. - M .: Mir, 1982.-406s.
- Edsger W. Dijkstra. Harmful // Go of Statement Considered // Communications of the ACM 11, March 1968. 147-148.
- Niklaus Wirth. Good Ideas, through the Looking Glass // Computer, V. 39, No 1, January 2006.
- Donald E. Knuth. Computing Surveys, V.6, No.4. December 1974.
- Frederick Brooks. The mythical man-month or how software systems are created .: Trans. from English - M .: Symbol Plus, 2001.-304s.
- Karev A.A. Code # code .