Thread: Gotos for good error handling practice?

  1. #1
    Registered User
    Join Date
    May 2009
    Location
    Look in your attic, I am there...
    Posts
    92

    Gotos for good error handling practice?

    I have been told (and understand) why goto's are a bad programming practice. But is it acceptable to use goto's for only error handing?

    example:
    Code:
      int Load_Character
      (
        const char       *File_Name,
        Struct_Character *Character
      ){
    ...
                      if(Mesh->Number_Of_Triangles < 1)
                        goto Error_Corrupt_File;
                      Mesh->Triangles = (Struct_Triangle *)malloc(sizeof(Struct_Triangle) * Mesh->Number_Of_Triangles;
                      break;
                    case CHUNK_TRIANGLES:
                      for(int p = 0;p < Mesh->Number_Of_Triangles;p++)
                        if(Scan(Buffer, TOKEN_TRIANGLE "%d%d%d%d", &Temp_B,
                          &Mesh->Triangles[p][0], &Mesh->Triangles[p][1], &Mesh->Triangles[p][2]) != 4)
                          goto Error_Corrupt_File;
                      break;
                    case CHUNK_NUMBER_OF_WEIGHTS:
                      if(Scan(Buffer, TOKEN_NUMBER_OF_WEIGHTS "%d", &Mesh->Number_Of_Weights) != 1)
                        goto Error_Corrupt_File;
                      if(Mesh->Number_Of_Weights < 1)
                        goto Error_Corrupt_File;
                      Mesh->Weights = (Struct_Weight *)malloc(sizeof(Struct_Weight) * Mesh->Number_Of_Weights;
                      break;
                    case CHUNK_WEIGHTS:
                      for(int p = 0;p < Mesh->Number_Of_Weights;p++)
                        if(Scan(Buffer, TOKEN_WEIGHT "%d%d%f" TOKEN_SUBSECTION_START "%f%f%f" TOKEN_SUBSECTION_END,
                          &Temp_B,                       &Mesh->Weights[p].Joint,       &Mesh->Weights[p].Bias,
                          &Mesh->Weights[p].Position[0], &Mesh->Weights[p].Position[1], &Mesh->Weights[p].Position[2]) != 6)
                          goto Error_Corrupt_File;
                      break;
                    case CHUNK_MESHES_END:
                      if(Compare(Buffer, TOKEN_SUBSECTION_END) == FAILURE)
                        goto Error_Corrupt_File;
                      break;
                    default:
                      goto Error_Corrupt_File;
                      break;
                  }
                }
                if(Next_Line(&Input, &Buffer, TOKEN_COMMENT_PREFIX) == FAILURE)
                  goto Error_Corrupt_File;
              }
              break;
            default:
              goto Error_Corrupt_File;
              break;
          }
        }
        fclose(Input);
        return SUCCESS;
      Error_Corrupt_File:
        ERROR_CORRUPT(File_Name);
        if(i > CHUNK_COMMANDLINE)
          Free_Character(Character);
        fclose(Input);
        return FAILURE;
      Error_Opening_File:
        ERROR_OPENING(File_Name);
        return FAILURE;
      Error_Wrong_Version:
        ERROR_VERSION(File_Name, Temp_A, VERSION);
        fclose(Input);
        return FAILURE;
      }

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by 127.0.0.1
    But is it acceptable to use goto's for only error handing?
    Yes.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    May 2009
    Location
    Look in your attic, I am there...
    Posts
    92
    Excellent, thanks for the link Bayint Naung.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    You can think of a goto, for a case like this, as an exception. If you're fine with exceptions in languages like C++, then you should be fine with (at least, the concept of) jumping to an "error handler" in C.

    Of course, exceptions in C++ are less clumsy than jumping around with goto, and are more powerful, because they can propagate through functions (but see setjmp() and longjmp() to implement something similar in C); but the end result is very much the same. When an error occurs, you jump to a bit of code that knows how to handle it. One of the few uses where goto makes a whole lot of sense.

    I've actually done "fuller-blown" exception handling in C with setjmp() and longjmp(), in limited scopes. You'd have to write wrappers for a large chunk of the standard library (including platform-specific functions, if you use them) to have a complete exception-ready environment, which I don't think is worth it. But when you're dealing with a limited subset of functions that might return error over a few function calls, it can make code easier to read, especially when you wrap the setjmp() and longjmp() calls in macros. At some point, though, it probably makes sense just to switch to C++ (or Java, or ...)

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    278
    If I have to do a series of operations (like perform sequential queries of a RS232 device) I use a while construct like this
    Code:
    while(1) {
        if( power_up_device() < 0 ) {
            ret_val = ERROR_POWER_UP:
            break;
        }
        if( establish_comm() < 0 ) {
            ret_val = ERROR_ESTABLISH_COMM:
            break;
        }
        if( read_device_name() < 0 ) {
            ret_val = ERROR_READ_DEVICE_NAME:
            break;
        .
        .
        .
        }
    }
    
    return ret_val;
    You can also change the breaks to continues and use a retry counter...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Error handling...
    By XSquared in forum C Programming
    Replies: 5
    Last Post: 07-13-2003, 03:57 AM
  2. Good C programming practice
    By Juganoo in forum C Programming
    Replies: 4
    Last Post: 12-21-2002, 03:20 AM
  3. Error handling
    By mepaco in forum C++ Programming
    Replies: 12
    Last Post: 09-06-2002, 10:45 AM
  4. if, then, and gotos
    By Unregistered in forum C++ Programming
    Replies: 6
    Last Post: 04-03-2002, 05:56 AM
  5. good programming practice
    By Unregistered in forum C Programming
    Replies: 0
    Last Post: 02-26-2002, 08:09 AM