# Thread: Gotos for good error handling practice?

1. ## 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. Originally Posted by 127.0.0.1
But is it acceptable to use goto's for only error handing?
Yes.

3. Excellent, thanks for the link Bayint Naung.

4. 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 ...)

5. 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 ) {