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;
}