A deep dive into the goto statement in embedded C programming
INDUSTRIAL LCD DISPLAYS / IGBT MODULES DISTRIBUTOR

Infineon / Mitsubishi / Fuji / Semikron / Eupec / IXYS

A deep dive into the goto statement in embedded C programming

Posted Date: 2024-01-22

What is a goto statement?

The goto statement is called a jump statement in C language.

Used to jump to other tags unconditionally. It transfers control to other parts of the program.

The goto statement is generally rarely used because it makes the program less readable and complex.

grammar

goto label;

goto statement example

Let's look at a simple example that demonstrates how to use the goto statement in C language.

Open Visual Studio, create a project named: goto, and create a source file in this project: goto-statment.c, the code is as follows:

#include void main() { int age; gotolabel: printf("You are not eligible to vote! "); printf("Enter you age: "); scanf("%d", &age); if (age

Execute the above code and get the following results

You are not eligible to vote! Enter you age: 12 You are not eligible to vote! Enter you age: 18 You are eligible to vote!

Why is it so unpopular?

More than twenty years ago, when computer programming was in its infancy, program flow was controlled by the "GOTO" statement.

This type of statement allows the programmer to break the current line of code and directly enter a different code segment.

Listing 1 is a simple example.

picture

Programming languages ​​finally began to introduce the concept of functions, which allowed programs to break lines of code.

If this is done, the goto statement is no longer used to indicate a line break in the code.

After the function is called, the function will loop back to the next instruction. Listing 2 is an example.

picture

This approach improves program structure and improves readability. Since then, this has been considered the correct way to write programs.

Just seeing or thinking about goto statements can make software engineers recoil in instinctive disgust.

The explanation on Wikipedia is;

The GOTO statement has been the target of criticism and debate. The main negative impact of using the GOTO statement is that the program'sPoor readabilityor even become unmaintainable "noodle code".

As structured programming became more popular in the 1960s and 1970s, many computer scientists concluded that programs should always use what is called "structured" control flow, and if -then-else statement to replace GOTO.

Even today, many programming style coding standards prohibit the use of GOTO statements.

There are also many people who defend the GOTO statement. They believe that as long as the use of the GOTO statement is restricted, it will not lead to low-quality code, and in many programming languages, some functions are difficult to implement without using the GOTO statement.

For example, the implementation of finite state machines, jumping out of nested loops, exception handling, etc.

Probably the most famous criticism of GOTO is a 1968 paper by Edsger Wybe Dijkstra called "GOTO Statements Harmful Wheels".

Dijkstra believed that the unrestricted use of GOTO statements should be eliminated from high-level languages ​​because it complicates the task of analyzing and verifying program correctness (especially involving loops).

Another point of view appears in Knuth's Structured Programming with go to Statements (3). The article analyzes many common programming tasks and then finds that some of them use GOTO to get the most ideal structure.

Limit GOTO

Many languages, such as C and Java, provide related control flow statements, such as break and continue, which are effectively restricted goto statements.

Their function is to jump unconditionally, but they can only jump to the end of the loop block - continue to enter the next loop (continue) or end the loop (break)

switch/case structure

The switch statement in C, C++, and Java efficiently implements a multi-way goto, with the jump target selected by the value of the expression.

This also leads to no reason why we have to use goto.

In view of these, the current usage of goto is as follows:

The result of the goto statement: The goto statement is retained in high-level programming languages ​​such as C/C++, but it is recommended not to use it or to use it sparingly.

Some newer high-level programming languages, such as Java, do not provide the goto statement. Although it specifies goto as a keyword, it does not support its use, making the program concise and easy to read;

Despite this, later C# still supports the goto statement. One advantage of the goto statement is that it can ensure that the program has a unique exit and avoid too large if nesting.

On the other hand, the goto statement is only discouraged, of course not banned.So under what circumstances can the goto statement be used??

Consider using goto:

Jump directly out of multiple loops;

Clear resources on error;

A situation that can increase the clarity of a program.

Unrestricted use of goto: destroys the clear program structure, makes the program less readable, and even becomes unmaintainable "noodle code".

It often brings errors or hidden dangers. For example, it may skip the construction of certain objects, initialization of variables, important calculations and other statements.

The following about using goto statementsin principleIt can be used as a reference for readers.

The goto statement can only goto to the same function, but cannot goto from one function to another function.

When using the goto statement to perform goto within the same function, the starting point of goto should be the end of a small function within the function, and the destination label of goto should be the start of another small function within the function.

You cannot goto from a position in a complex execution state to another position. For example, jumping out of multiple nested loop judgments is not allowed.

Jumps like two directions should be avoided. This is most likely to lead to "noodle code".

Students who have read the Linux kernel code should notice that goto statements are actually used in many places in the Linux kernel code.

This is the i2c_dev_init function in /drivers/i2c/i2c-dev.c:

static int __init i2c_dev_init(void) { int res; pr_info("i2c /dev entries driver "); res = register_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS, "i2c"); if (res) goto out; i2c_dev_class = class_create (THIS_MODULE, "i2c-dev"); if (IS_ERR(i2c_dev_class)) { res = PTR_ERR(i2c_dev_class); goto out_unreg_chrdev; } i2c_dev_class->dev_groups = i2c_groups; /* Keep track of adapters which will be added or removed later * / res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); if (res) goto out_unreg_class; /* Bind to already existing adapters right away */ i2c_for_each_dev(NULL, i2cdev_attach_adapter); return 0; out_unreg_class: class_destroy(i2c_dev_class); out_unreg_chrdev: unregister_ch rdev_region(MKDEV (I2C_MAJOR, 0), I2C_MINORS); out: pr_err("Driver Initialization failed "); return res; }

But you will find that the goto statements in these places are used very carefully and basically follow the principles mentioned above.

Review Editor: Huang Fei


#deep #dive #goto #statement #embedded #programming