📜 ⬆️ ⬇️

The forbidden fruit of GOTO is sweet!

Good day!

What is your attitude to the goto operator in C / C ++ languages? Most likely, when you learned to program, you used it. Then you learned that it was bad, and you forgot about it. Although sometimes with complex error handling ... no, no, there try ... throw ... catch. Or to exit nested loops ... no, there are flags and a lot of difficulties. Or when nested switches ... no, no, no, there the same flags.
And yet, sometimes in the stillness of the night you would allow a sinful thought into your subconscious mind - “why not use the goto here ? And the program seems to be slimmer, and optimally out. Yes, it would be good ... But no - it is impossible , they forgot! ”.
Why is it so?
Under the cut - a small investigation and mine, based on years of practice and different platforms, attitude to this issue
UPD: here the article considers C and C ++, programming for PC and slightly for microcontrollers. There is another article about microcontrollers.

Request to goto's ardent opponents - do not overthrow me into hell fire minus karma just because I raised this topic and I am a partial supporter of goto!

A small historical excursion


Those who, even without me, know perfectly well what a combinational circuit is, a circuit with memory, and how an assembler grew out of it - you can safely jump further - to a conclusion.

It all started with combinational circuits



At the beginning there was a word - and the word was a function. It is not so important that it was a Boolean function of a logical variable - then, in this basis, they managed to implement all (almost) mathematics, and then texts, graphics ... Anyway, it turned out that with the help of computer technology it is very convenient to do arithmetic, and then trigonometric and other actions and find the values ​​of the functions of the variable.
')
In other words, you had to make a device that, by the value of a variable (variables), found the value of a function.

To solve this difficult task, a sequential algorithm was built to perform arithmetic operations (in the case of a given accuracy of calculations in such an algorithm, each arithmetic operation can be performed in one clock).

Having an algorithm, it is easy to construct a combinational circuit - a circuit that instantly (up to the response of logic devices and signal propagation time) gave the answer at the output.
The question is - do you need any transitions? No, they are simply not there. There is a consistent course of action. All these actions can be implemented ultimately in a single cycle (I don’t argue, it will be very, very cumbersome, but given the digit capacity of all the data, any student will build such a scheme for you - and even more so a synthesizer for VHDL or Verilog).

But then the memory circuits intervened.



And then someone's clever head came up with a scheme with feedback - for example, an RS trigger. And then the state of the scheme appeared. And the state is nothing but the current value of all the elements with memory.

The appearance of such memory elements made it possible to make a revolutionary leap forward from hard-coded devices to firmware automata. Simply put, there is a command memory in firmware automata. There is a separate device that implements the current firmware (addition, subtraction, or something else). But the choice of "current" firmware is a separate device - let it be a "sampling device".

The question is - are there any transitions? Definitely yes! Moreover, there are unconditional transitions (the address of the next command does not depend on the current state of the data) and conditional (the address of the next command depends on the state of the data).

Is it possible to do without them? No way! If we don’t use transitions, we’ll go back to the memoryless combinational circuit.

As a result, we come to the assembler


The apotheosis of such computing devices are micro, simple and super computers. All of them are based on a language of codes, which is rather easily converted into an Assembler with an approximately identical set of instructions. Let's take the most popular personal computer with an assembler from an i386 processor - good, Windows XP is written for it. How is his work built?

In this processor, the memory of data and commands is shared, is identified by the address. Commands do not have a fixed length. If a transition command is not used, then the next command executes the command located immediately after the current one.

There is also a set of goto commands. They are unconditional (just go to the next address - jmp, go to the subroutine - call, exit it - ret, call the interrupt - int) and conditional (depending on the state of the flags - jnz, jne, jz, ...). There is also a command for creating loops - loop. It 1) makes -1 the CX / ECX register and 2) goes to the specified address if this register is nonzero.
In terms of transition operations, other mass assemblers (the same microcontrollers) are not fundamentally different - unless there is no possibility for a program to cause an interrupt and there is not a loop everywhere.
I declare with all responsibility - it is impossible to do without transition operations in assembler! Any program in assembly language is just full of them! However, there is no one to argue with me here, I think it will not.

Total


What can be summed up? At the microprocessor level, transition operations are used very actively. It’s almost impossible to write a real program that doesn’t use them (maybe it can be done, but it will be a super-mega perversion and certainly not a real program!). Nobody will argue with this either.

But why, then, in higher-level languages, let's concentrate on C / C ++ - did the goto operator suddenly fall into disfavor? ..

Little about algorithms




And now we will look at the cunning algorithm. I have no idea what this nonsense is, but it must be implemented.

UPD : here A, B, C, D, E are some operations , not a function call! It is possible that they use a lot of local variables. And it is quite possible that they change their state. That is, in this case we are not talking about calling functions - some actions will not be detailed.

Here’s how it looks in C with goto:

if (a)
{
	A;
	goto L3;
}
L1:
if (b)
{
L2:
	B;
L3:
	C;
	goto L1;
}
else if (!c)
{
	D;
	goto L2;
}
E;
 


. — ! goto:

char bf1, bf2, bf3;

if (a)
{
	A;
	bf1 = 1;
}
else
	bf1 = 0;

bf2 = 0;
do
{
	do
	{
		if (bf3 || b)
			bf3 = 1;
		else
			bf3 = 0;
		if (bf3 || bf2)
			B;
		if (bf3 || bf1 || bf2)
		{
			C;
			bf1 = 0;
			bf2 = 1;
		}
		if (!bf3)
		{
			if (!c)
			{
				D;
				bf3 = 1;
			}
			else
			{
				bf3 = 0;
				bf2 = 0;
			}
		}
	}
	while (bf3);
}
while (bf2);

E; 


- ?..
:



goto!

, . .

goto



20- , ActiveHDL, , , ( , ). , - . , , – — , .

… , .

goto


, goto – . for (…), while (…) {…}, do {…} while (…). switch (…) {case … case …}. / break continue. , funct() return.

++ , . – try {… throw …} catch (…) {…}.

goto «» — goto?

goto


, , . . – , !

– .
– , - , . ! , ++ ? ++ («» , ): , , , , … , ++… , , – « ».

, – ? - . 220 – ! – .

goto. – .

– , , . ? – , ! , - ! , – . !

, , a = ++i , i = i + 1; a = i. , ?

, C++ , goto :

goto Label;

for (;;)
{
	int p = 0;
Label:
	p += 10;
}


p? ! , – , p .

– Visual Studio 2008.
? , - goto . , . .



++ try … throw … catch. . ++ — , . goto. , . – , , .

, goto. «» , UART, USB . .



:

char a, b, c;

for (a = 0; a < 10; ++a)
{
	for (b = 0; b < a; ++b)
	{
		if (!c)
			goto Leave;
	}
	for (b = 10; b < 15; ++b)
	{
		d ();
	}
}

Leave:
e ();


– ? . - – .

:

char a, b, c, f1;

f1 = 1;
for (a = 0; a < 10 && f1; ++a)
{
	for (b = 0; b < a && f1; ++b)
	{
		if (!c)
			f1 = 0;
	}
	if (f1)
	{
		for (b = 10; b < 15; ++b)
		{
			d ();
		}
	}
}

e ();


? . . , «» PC. – .

, ( , Java) break Leave. goto, !

switch (…) { case …}. .

UPD: , , ++. ++ «» throw… catch…. , throw… catch… — goto!



? ? , ( boost::spirit). , « » — , ; , . goto …

, ++ , . . , , goto?.. – , . . – .



- :

int f (…)
{
	…
	if (a)
	{
		c = 15;
		return 10;
	}
	…
	if (b)
	{
		c = 15;
		return 10;
	}
	…
	 = 10;
	return 5;
}


:

int f (…)
{
	…
	if (a)
		goto Exit;
	…
	if (b)
		goto Exit;

	…
	 = 10;
	return 5;
Exit:
	c = 15;
	return 10;
}


? - . . goto. .
, …



! . – , !

, , goto .
– goto .

UPD: , goto .

goto:

goto:


/? , .

Source: https://habr.com/ru/post/114211/


All Articles