Introduction
The goto in c Programming can transfer a program’s control directly to a label within the current function in the code. It allows the program to jump from one part of the code to another. This keyword is generally considered harmful because it could lead to less readable code. However, there are some still some good use cases with the goto
keyword that you can utilize.
Typical Function with Error Checking
I like to use goto
in a function that allocates and frees memory and returns different error codes for different errors. The goto
keyword not only increase the code coverage
(a metric to measure your quality of code as higher code coverage the better) but also makes you write less code when error occurs.
Consider this function below that has a memory allocation inside and at the same time checks for several possible errors and will return the error code to function caller immediately when it finds an error.
/* this function returns 0 on success or negative numbers on error */ int gotoExample(const char * name, const char * occupation, int age) { int ret = -1; char * some_resource = NULL; some_resource = (char * ) malloc(20); if (!some_resource) { printf("failed to allocate memory\n"); goto error; } if (!name) { ret = -2; if (some_resource) free(some_resource); return ret; } if (age < 0) { ret = -3; if (some_resource) free(some_resource); return ret; } if (!occupation) { ret = -4; if (some_resource) free(some_resource); return ret; } ret = 0; if (some_resource) free(some_resource); return ret; }
While the above example is perfectly fine, it has a lot of redundant codes. The function has to call the free()
routine to release the memory allocated to some_resource
before the function returns. Since there are 4 places of possible returns, there are 4 copies of such code added. What if you forget about one? Then you will get yourself a memory leak problem, which of course we do not want. In addition, if this function returns in the middle of it due to an error, the rest of the function is not run. This is not a desirable practice because it lowers its code coverage
rating. Code coverage is one of the popular metrics to measure a program’s effectiveness and higher code coverage the better.
Improve Above Function With Goto Keyword
How to improve the above example? Simple. Use goto in C programming!
Instead of having 4 return
keywords and free()
routines, we will just have one at the end of the function, but this time, we add a label called error
right after ret = 0
line (which indicates a success case). The error
label is the destination of the goto
keyword that we will put inside each if statement
that checks for a particular error. In other words, instead of return
in the middle of the function when an error is found, we set the proper error code and jump to the error
label, which will release the allocated memory and return the error code. This eliminates redundant codes and make it more organized and readable. Also, because this function returns at the end of it, the code coverage rating for this function would be high.
/* this function returns 0 on success or negative numbers on error */ int gotoExample(const char * name, const char * occupation, int age) { int ret = -1; char * some_resource = NULL; some_resource = (char * ) malloc(20); if (!some_resource) { printf("failed to allocate memory\n"); goto error; } if (!name) { ret = -2; goto error; } if (age < 0) { ret = -3; goto error; } if (!occupation) { ret = -4; goto error; } ret = 0; error: if (some_resource) free(some_resource); return ret; }
Summary
Personally, I found the goto
keyword the most useful to reduce code redundancy and improve code coverage as illustrated in the examples above. There are other use cases such as retry a particular block of code if it fails to execute by jumping the program in front of it to try again. This could work but it is best to use loops to handle the retry for cases like this.
Related Pages
- A Deeper Look At The If Statement In C
- How Not To Exploit The C Loops
- Common Usages of The C Switch Statement
Hi, this is Cary, your friendly tech enthusiast, educator and author. Currently working as a software architect at Highgo Software Canada. I enjoy simplifying complex concepts, diving into coding challenges, unraveling the mysteries of software. Most importantly, I like sharing and teaching others about all things tech. Find more blogs from me at highgo.ca