[Good Programming habits] use the goto statement properly

Source: Internet
Author: User

Goto statements are notorious in C/C ++, and even some books or company programming specifications. The result is that when some programmers see the goto statement being used in a program, they instinctively think that the program is "junk ". In addition, some programmers feel that they are not professional because they use the goto statement. In fact, everything cannot be too radical. The use of goto statements can greatly simplify the program and improve the readability and maintainability of the program. Before starting to illustrate its benefits, we should first use some statistical data to show that the goto statement has not been abandoned due to the "Notorious" nature. These statistics may not be accurate but convincing. For the operating system, the Linux-2.6.21 kernel uses 20,333 goto statements, the VxWorks-6.2 uses 9142, And the last 941 goto statements are applied to the rtems-4.9.2; and, the glibc-2.9 library uses 1750 goto statements. All these statistics show that the key to disabling a goto language is to use it properly.

Figure 1 shows a function that is not written using a goto statement. Code for handling multiple errors, such as 113 ~ 115 rows, 120 ~ 122 rows and 126 ~ 129 rows. With this distributed error processing, it is easy to omit and release the previously allocated resources, resulting in resource leakage. If you use the goto statement, you can achieve better results.

Example. c
00097: int queue_init (queue_t ** _ pp_queue, int _ size)
00098 :{
00099: pthread_mutexattr_t attr;
00100: queue_t * queue;
00101:
00102: queue = (queue_t *) malloc (sizeof (queue_t ));
00103: if (0 = queue ){
00104: return-1;
00105 :}
00106: * _ pp_queue = queue;
00107:
00108: memset (queue, 0, sizeof (* queue ));
00109: queue-> size _ = _ size;
00110:
00111: pthread_mutexattr_init (& attr );
00112: if (0! = Pthread_mutex_init (& queue-> mutex _, & attr )){
00113: pthread_mutexattr_destroy (& attr );
00114: free (queue );
00115: return-1;
00116 :}
00117:
00118: queue-> messages _ = (void **) malloc (queue-> size _ * sizeof (void *));
00119: if (0 = queue-> messages _){
00120: pthread_mutexattr_destroy (& attr );
00121: free (queue );
00122: return-1;
00123 :}
00124:
00125: if (0! = Sem_init (& queue-> sem_put _, 0, queue-> size _)){
00126: free (queue-> messages _);
00127: pthread_mutexattr_destroy (& attr );
00128: free (queue );
00129: return-1;
00130 :}
00131:
00132: pthread_mutexattr_destroy (& attr );
00133:
00134: return 0;
00135:} Figure 1

Figure 2 shows another version written using the goto statement. Compared with the version without the goto statement, the program is simpler, in most cases, the goto statement is used to jump to the end of the program for handling errors. The goto statement can be used in addition to the error handling in the example here, but also in other program logic to simplify the program and improve readability.

Example. c
00053: int queue_init (queue_t ** _ pp_queue, int _ size)
00054 :{
00055: pthread_mutexattr_t attr;
00056: queue_t * queue;
00057:
00058: queue = (queue_t *) malloc (sizeof (queue_t ));
00059: if (0 = queue ){
00060: return-1;
00061 :}
00062: * _ pp_queue = queue;
00063:
00064: memset (queue, 0, sizeof (* queue ));
00065: queue-> size _ = _ size;
00066:
00067: pthread_mutexattr_init (& attr );
00068: if (0! = Pthread_mutex_init (& queue-> mutex _, & attr )){
00069: goto error;
00070 :}
00071:
00072: queue-> messages _ = (void **) malloc (queue-> size _ * sizeof (void *));
00073: if (0 = queue-> messages _){
00074: goto error;
00075 :}
00076:
00077: if (0! = Sem_init (& queue-> sem_put _, 0, queue-> size _)){
00078: goto error1;
00079 :}
00080:
00081: pthread_mutexattr_destroy (& attr );
00082:
00083: return 0;
00084:
00085: error1:
00086: free (queue-> messages _);
00087: error:
00088: pthread_mutexattr_destroy (& attr );
00089: free (queue );
00090: return-1;
00091:} Figure 2

Pay attention to the following principles when using the goto statement:
1) do not use it excessively. The 60 rows in step 2 do not use the goto statement to jump to the end of the program. The reason why goto is not used here is to facilitate reading. Because the program has not allocated resources at this time, the direct return is more straightforward. In addition, if a goto statement exists in this function, it means that an error occurs and resources need to be released. If you change the statements of 60 rows to goto, the consistency of the use of goto statements in this function is broken.
2) Do not let the goto statement form a ring. Use the goto statement to form a line from one point to another. Of course, if the use of the goto statement does not undermine readability, you can consider breaking this principle.

This article from "to Jane Li cloud" blog, please be sure to keep this source http://yunli.blog.51cto.com/831344/248828

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.