An analysis of the Goto of C language

Source: Internet
Author: User

1. The confusion points when reading the code:

Static intDo_bind (Const Char*host,intPortintProtocolint*family) {    intFD; intstatus; intReuse =1; structAddrinfo ai_hints; structAddrinfo *ai_list =NULL; Charportstr[ -]; if(host = = NULL | | host[0] ==0) {host="0.0.0.0";//Inaddr_any} sprintf (Portstr,"%d", Port); memset (&ai_hints,0,sizeof(ai_hints)); Ai_hints.ai_family=Af_unspec; if(Protocol = =ipproto_tcp) {Ai_hints.ai_socktype=Sock_stream; } Else{assert (protocol==ipproto_udp); Ai_hints.ai_socktype=Sock_dgram; } Ai_hints.ai_protocol=Protocol; Status= Getaddrinfo (host, Portstr, &ai_hints, &ai_list); if(Status! =0 ) {        return-1; }    *family = ai_list->ai_family; FD= Socket (*family, Ai_list->ai_socktype,0); if(FD <0) {        Goto_failed_fd; }    if(SetSockOpt (FD, Sol_socket, SO_REUSEADDR, (void*) &reuse,sizeof(int))==-1) {        Goto_failed; } Status= Bind (FD, (structSOCKADDR *) ai_list->ai_addr, ai_list->Ai_addrlen); if(Status! =0)        Goto_failed;    Freeaddrinfo (ai_list); returnFd;_failed:close (FD); _failed_fd:freeaddrinfo (ai_list); return-1;}Static intDo_listen (Const Char* Host,intPortintbacklog) {    intFamily =0; intLISTEN_FD = Do_bind (host, Port, IPPROTO_TCP, &family); if(Listen_fd <0) {        return-1; }    if(Listen (listen_fd, backlog) = =-1) {close (LISTEN_FD); return-1; }    returnlisten_fd;}

This is a piece of code to create a protocol-independent listening socket, where three of the goto statements are used, because the getaddrinfo (...) is called in front of it. ) function, the function will automatically request the kernel space, so you need to call Freeaddrindo (...) after the end. To free up space.

But when reading Goto _failed, there is confusion because _failed: the label has only one close (FD);

Since this knowledge point has not been used before, I think that after close (FD) will exit the function directly, so wondering why not call getaddrinfo (...), also thought is the author's fault (...), but I think it can not be the author's question, the results view k&r< <c programming language >> related content, found to be their own problem ...

The original Goto is generally run to the Mark pointed to the Goto statement, so that the program starts from the label down execution, generally to skip the call goto start to the middle of the label to execute the role of code. In the example above, when _failed:close (FD) is called, the function does not exit, but continues execution, then calls the statement at _FAILED_FD: until the return-1 program ends.

This invokes the Freeaddrinfo (...). Doubts are solved.

2.goto Analysis:

1). What does Goto do?

The C language provides the discretionary use of the Goto statement and the marking of the jump position. But in theory, Goto is not necessary.

Mark the marking of the jump position: As in the above example, _failed:, _FAILED_FD:, the label can be anywhere in the function, behind the label, write processing logic.

Call goto statement Syntax: "goto label;"

2) Test Code:

  

#include <stdio.h>#include<stdlib.h>intMain (intargcChar*argv[]) {    intA = Atoi (argv[1]); if(A = =1)    {        Gotofailed1; }    Else if(A = =2)    {        GotoFailed2; }    Else    {        Gotofailed3; } failed1:printf ("Get failed1\n"); failed2:printf ("Get failed2\n"); failed3:printf ("Get failed3\n"); printf ("A + b = 3\n"); (Random output)return 0;}

The code enters a value from the console, the following is the result of a = 1, 2, 3 o'clock, compiled: gcc-g-o test test.c

Console input:./test 1

Results:

Get failed1

Get Failed2

Get Failed3

A + b = 3

Console input:./test 2

Results:

Get Failed2

Get Failed3

A + b = 3

Console input:./test 3

Results:

Get Failed3

A + b = 3

As you can see, after running to the corresponding label, the program continues to run down.

To modify the code:

Move the _failed1: code to the top of the if (a = = 1) and modify the value of a:

#include <stdio.h>#include<stdlib.h>intMain (intargcChar*argv[]) {    intA = Atoi (argv[1]); failed1:printf ("Get failed1\n"); A= 3; if(A = =1)    {
printf ("a = 1\n"); Gotofailed1; } Else if(A = =2) { GotoFailed2; } Else { Gotofailed3; }failed2:printf ("Get failed2\n"); failed3:printf ("Get failed3\n"); printf ("A + b = 3\n"); return 0;}

When you compile the code again and run:

./test 1

Output Result:

Get failed1

Get Failed3

A + b = 3

As can be seen, the label only play a role, the program sequence execution, the label as if it does not exist, first output get failed1, and then modify a = 3,. Not only the Goto designator is called, then the program is transferred to the label, which triggers the code below the label to start running. Instead, it can be thought of as inserting a label into the complete code, which simply directs the goto location.

3) Why is it not recommended to use Goto:

It is generally considered that the use of Goto will cause code to be difficult to understand and maintain, PS: because I use less, this understanding is not very deep.

4) What is the use of goto:

When the program has multiple layers of nesting, when the logic in the nest is true or false, need to completely or continuously jump out of several layers of cycle, generally consider using Goto, because the break can only jump out of a layer, and need to jump out of the multilayer loop if more judgment logic,

In this case, you will consider using Goto, and you will generally consider using Goto when dealing with complex logic in a large program.

For example, if you determine whether there are identical elements in two arrays:

  

//Use goto for(i =0, I < n; ++i) {     for(j =0, J < M; ++j) {if(A[i] = =B[j]) {            Gotofound; }}}found: ...//Do and use goto for(i =0, I < n; ++i) {     for(j =0, J < M; ++j) {if(A[i] = =B[j]) {Found=true;  Break; }    }    if(found) { Break; }}......

In short, put double-edged sword.

First summed up here, the article inevitably such a mistake, welcome correction.

An analysis of the Goto of C language

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.