Thread: Does C have a GOTO function

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    6

    Does C have a GOTO function

    I'm trying to learn C, then I'll learn C++. What I know now is some VB and QB.

    I know that in QB, I could do something like

    if a < b then goto AisSmaller

    AisSmaller:
    Print "A is smaller than B"
    END

    Is there anyway in C, to tell it to go to a specific place if a certain condition is TRUE? I know you can always evaluate a condition and then use brackets, but this could get repetive you know?

  2. #2
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Code:
    if( a < b ) goto AisSimilar;
    
    AisSimilar:
    printf( "A is smaller than B\n" );
    
    exit( 0 );
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  3. #3
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Yes, there is a way. There is a goto command. Having said that, I will not give you the syntax. Why?

    BECAUSE YOU DON'T NEED GOTO IN C. (There may be some special exceptions, which we've attempted to discover on this board without much success. However, you are unlikely to encounter a need for goto in regular coding, especially at your level. To teach it to you now would be to tempt you to use it)

    Gotos can be avoided (which is good) with the following things (I might miss some)
    functions (and the return statement)
    if statements
    while loops
    for loops
    do...while loops
    switch...case statements
    try...throw...catch (is that C++ specific?)
    classes (these are C++ specific)
    exit (a bit of a stretch)

    edit: Oh no, XSquared gave you the syntax and now you'll probably use goto all the time. May God save you.
    Away.

  4. #4
    Registered User
    Join Date
    Jul 2003
    Posts
    102
    A good programmer should avoid goto statements is what blackwart said...
    Saravanan.T.S.
    Beginner.

  5. #5
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Yes, that's what blackrat said :P You don't need to use gotos, and they make code slower and harder to read.
    Away.

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    6
    Hey thanks for the syntax for goto, but maybe I won't use it if it's so bad

    I am just starting, and you are right, I want to learn the right way up front....but those other examples you give...I don't get.

    For instance, you know how you can use brackets right, like:

    Code:
    if a < b 
              {
                   printf ("blah blah")
                    a = j + k
               }
    Ok, now that seems fine, now lets say that later in the program, I want it to do something like this:
    Code:
    if d < c
             {
                  printf ("blah blah")
                  a = j + k
               }
    In other words, if either A is less than b, or d is less than c, I want it to execute the same exact code, but it seems foolish to have to type the exact same code ("printf and a=j+k") over and over in brackets everytime, when I need a way to simply refer it to a certain place that already has the specified code, know what I mean?

  7. #7
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    There are a number of ways that you could have that code you used as an example. You could stick the two lines of code in a function, which could be called from the if statements (a bit silly in this example, but a great way for doing more complex things)

    Or, you could just leave it like you had in your example. That's not actually bad. The extra lines won't slow down your program at all, and they'll be read into the cache and accessed instantly when the program gets up to that point (guys, don't nitpick me, I'm speaking on general terms here...) If you stuck in a goto instead, the execution of the code would have to jump to another spot, which would have to first be found and read into the cache, which would undoubtedly slow things up a lot - and it makes your code hard to read. Also, suppose you changed your code to this:

    Code:
    int main()
    {
             ...
    	if (a<b)
    		goto print;
    	if (c<d)
    		goto print;
    
    	print:
    		printf("blah blah blah\n");
    		a = j + k;
    
    	return 0;
    }
    First, that's a very simplistic example, but you can already see that it's hard to read. Execution isn't what you might expect, either. If a<b, the program will jump to print:, execute a couple statements, and end. If a isn't < b, then it will go to the second if statement. To control the flow of the program in the way that you would expect (from the way your post sounded) would require multiple gotos and multiple labels and more if statements - yuck. Or you could just stick in the extra two lines of code, and it would be a lot better.

    Or if it's a big long block of code instead of two lines, and it's going to be executed from several places, stick it in a function and call the function. I think I've rambled enough now, hopefully I've answered your question.
    Away.

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    6
    As usual, you guys are very helpfull.

    Ok, I think that I will stick to brackets most times, but can you please tell me how I can "call a function". I know I should know this, but I don't as of yet!

    That way, I can do it in the future if I need to (call a function that is)

  9. #9
    Registered User
    Join Date
    Jul 2003
    Posts
    61
    blackrat, your code could be simplified even more, like this:
    Code:
    	if (a<b || c <d) {
    		printf("blah blah blah\n");
    		a = j + k;
    }
    $ENV: FreeBSD, gcc, emacs

  10. #10
    Registered User
    Join Date
    Aug 2003
    Posts
    4
    You shouldn't assume 'goto' is evil.

    In some cases, the use of a goto can make code more efficient, and more readable.

    If you want to create a single, local exception handler within a C function (not C++), the most practical way is with the use of goto. Consider the following code segment:

    Code:
    int create_client_socket(struct sockaddr_in *addr)
    {
      int fd;
    
      if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        goto exception;
    
      if (connect(fd, addr, sizeof(*addr)) == -1)
        goto exception;
    
      return fd;
    
      exception:
        fprintf(stderr, "%s: %s", __func__, strerror(errno));
        return -1;
    }
    Remember this is only an example (true error handling not shown). I would argue that this is more readable than the alternative version; which would include redundant fprintf's at each possible error stage.

    You could have a default error handling routine - but sometimes you need to handle error's specifically. The above code really represents what you would call an 'exception handler' in other languages.

    The generated code for the above routine may also be less than that of the redundant fprintf counterpart.

    Goto is not a purist's recommendation - but sometimes it does have its uses. If you want further proof, try viewing the linux kernel source.

  11. #11
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by trido
    You shouldn't assume 'goto' is evil.
    No but you shouldn't necessarily use it just because you can
    Code:
    #define ERROR_VAL  -1
    int create_client_socket(struct sockaddr_in *addr)
    {
      int fd;
    
      if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR_VAL)
        goto exception;
    
      if (connect(fd, addr, sizeof(*addr)) == ERROR_VAL)
        goto exception;
    
      return fd;
    
      exception:
        fprintf(stderr, "%s: %s", __func__, strerror(errno));
        return -1;
    }
    The following is quite readable for most C programmers and does not rely on a goto...
    Code:
    int create_client_socket(struct sockaddr_in *addr)
    {
        int fd;
    
        if ((fd = socket(AF_INET, SOCK_STREAM, 0)) != -1)
        {
            if (connect(fd, addr, sizeof(*addr)) != -1)
            {
                return fd;
            }
        }
        fprintf(stderr, "%s: %s", __func__, strerror(errno));
        return -1;
    }
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  12. #12
    Registered User
    Join Date
    Jul 2003
    Posts
    102
    I feel very sorry about phreedom. He asked about goto but discussion goes to socket programming...
    Saravanan.T.S.
    Beginner.

  13. #13
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    > Yes, that's what blackrat said :P You don't need to use gotos, and they make code slower and harder to read.

    It does not make it necessarily slower. It is also possible to produce very slow code without using even one goto in your code. But it can make your code hard to read, debug and maintain if you use a lot of goto's in your code. As already said, it is not necessary to use goto in C.

    > The following is quite readable for most C programmers and does not rely on a goto...

    Personally I'd prefer to have only one place in a function where a return is done, at the end of the function. In smaller functions it may probably be not a big problem to have more than one return, but I found that especially in large functions it is hard to read a function with lots of returns. Often in such situation the number of returns can be reduced by breaking the function op in smaller functions. It may be a bit more inefficient in run-time, but if the function is not called very often, then the inefficiency is very small and can be ignored in the total process.

    Code:
    int create_client_socket(struct sockaddr_in *addr)
    {
        int fd = -1;
        int retval = -1;
    
        fd = socket (AF_INET, SOCK_STREAM, 0);
        if (fd != -1)
        {
            retval = connect (fd, addr, sizeof (*addr);
        }
        
        if (-1 == retval)
        {
            fprintf (stderr, "%s: %s", __func__, strerror (errno));
        }
    
        return retval;
    }

  14. #14
    Registered User
    Join Date
    Aug 2003
    Posts
    4
    Originally posted by WaltP
    The following is quite readable for most C programmers and does not rely on a goto...
    Code:
    int create_client_socket(struct sockaddr_in *addr)
    {
        int fd;
    
        if ((fd = socket(AF_INET, SOCK_STREAM, 0)) != -1)
        {
            if (connect(fd, addr, sizeof(*addr)) != -1)
            {
                return fd;
            }
        }
        fprintf(stderr, "%s: %s", __func__, strerror(errno));
        return -1;
    }
    Yuk. As I said, what I posted was purely an example. Who wants four levels of nesting when it comes to writing the server routine? Nesting reduces readability.

    Also, #def'ing ERROR_VAL is superfluous. Error values from system calls don't change - constants are acceptable.

    Code:
    
    int create_client_socket(struct sockaddr_in *addr)
    {
        int fd = -1;
        int retval = -1;
    
        fd = socket (AF_INET, SOCK_STREAM, 0);
        if (fd != -1)
        {
            retval = connect (fd, addr, sizeof (*addr);
        }
        
        if (-1 == retval)
        {
            fprintf (stderr, "%s: %s", __func__, strerror (errno));
        }
    
        return retval;
    }
    
    Why on earth would you delay the obvious? You're making an extra comparison that you don't need. If you're ready to return, RETURN. If you find it difficult to comprehend multiple returns in a function, you probably shouldn't be writing code in C.

    P.S. If you're trying to avoid the old (var=num) expression in a test, don't you think that by writing a constant before an equality operator you're already completely aware of what you're trying to avoid?

  15. #15
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Originally posted by cc0d3r
    blackrat, your code could be simplified even more, like this:
    Code:
    	if (a<b || c <d) {
    		printf("blah blah blah\n");
    		a = j + k;
    }
    I thought of that, however, in this case it is NOT the same. Suppose the case of a=b=c=d. In the original code, the following would be executed twice:
    Code:
    printf("blah blah blah\n");
    a = j + k;
    In your modified code, it would only be executed once, which may not be the desired effect.
    Away.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  4. Maybe the GOTO function???
    By Mustang5670 in forum C Programming
    Replies: 3
    Last Post: 01-04-2004, 04:53 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM