Tuesday, April 29, 2008, 11:48 AM - Programming
Talking of the goodness of the goto statement in C programming is often considered evil. People would just rubbish you the moment you say “We can use a goto statement to do this .....”. The common cited usage of goto is to implement a break out of more than one level of for or while. I think I have realized another good situation to use the goto statement from my own experience. Take this example:
int function() {
SOME_STRUCT someStruct;
char* file = NULL;
char* folder = NULL;
char* drive = NULL;
HANLDE *ptr = NULL;
ptr = AtleastDoThat(file, folder, drive, & someStruct));
if (ptr == NULL) {
CloseHandle(ptr);
return 1;
}
file = new char[100];
if (!DoSomething(ptr, file)) {
CloseHandle(ptr);
delete[] file;
return 1;
}
folder = new char[100];
if (!DoSomethingElse(ptr, file, folder)) {
CloseHandle(ptr);
delete[] file;
delete[] folder;
return 1;
}
drive = new drive[100];
if (!AtleastDoThis(ptr, drive, file, folder)) {
CloseHandle(ptr);
delete[] file;
delete[] folder;
delete[] drive;
return 1;
}
return 0;
}In the above example we have a bunch of local variables which gets allocted progressively and its this function’s responsibility to clean before exit. There can be multiple exit points and you have to make sure to clean all of those variables that you have allocated some resource. In real time, this function will look very dirty and not as clean as simple new and delete[]. The problems with this code are:
1. As this function adds more code, there is a risk that the programmer will miss to clean up as he has to put the cleanup code at multiple places.
2. Readability is bad.
3. The reader has to un-necessary go through all the cleanup code while reading the actual logic. Attention is diverted.
Now take a look at this:
int function() {
SOME_STRUCT someStruct;
char* file = NULL;
char* folder = NULL;
char* drive = NULL;
HANDLE *ptr = NULL;
ptr = AtleastDoThat(file, folder, drive, & someStruct));
if (ptr == NULL) {
goto error;
}
file = new char[100];
if (!DoSomething(ptr, file)) {
}
folder = new char[100];
if (!DoSomethingElse(ptr, file, folder)) {
goto error;
}
drive = new drive[100];
if (!AtleastDoThis(ptr, drive, file, folder)) {
goto error;
}
return 0;
error:
ptr?CloseHandle(ptr):NULL;
file?delete[] file:NULL;
folder?delete[] folder:NULL;
drive?delete[] drive:NULL;
return 1;
}
The idea of discouraging goto is that people tend to misuse it by not writing elegant conditional jumps thereby reducing readability. In this case I find it increases readability. Many programmers use this technique. Thoughts?
Happy branching.//




( 3 / 44 )

Calendar




