Friday, October 27, 2006

When to Use goto in C/C++

Almost each and every text book on "C" language suggests not to use 'goto' in the code. But, there seem to be instances where 'goto' can be used very effectively. Do you know one?

Here is my answer on where to use it: Consider the following function accepting a set of arguments. Depending on necessity we the first job we would do would be to check validity of the parameters send to this argument. We would proceed and do the intended function only if the parameters are valid. One way to write would be
/*--------------------------------------------------
some_function : does some job.
arg1 - argument number 1
pStructArg - argument of type StructType contains
a - value for a
b - value for b
Returns : 1 - on success
-1 - on failure
--------------------------------------------------*/

int some_function (int arg1, struct StructType *pStructArg)
{
if (arg1 != valid_value_arg1) {
return -1;
}

if (pStructArg->a != valid_value_a) {
return -1;
}

if (pStructArg->b != valid_value_b) {
return -1;
}

/* Now do the real job */
...
...
...

return 1;
}

This above implementation has one disadvantage that there are multiple return points. Lets avoid that

int some_function (int arg1, struct StructType *pStructArg)
{
int status = 1;

if (arg1 == valid_value_arg1) {
status = -1;
}

if (pStructArg->a != valid_value_a) {
status = -1;
}

if (pStructArg->b != valid_value_b) {
status = -1;
}

if (status == 1) {
/* Now do the real job */
...
...
...
}

return status;
}

Now there is another problem, if arg1 was invalid then rest of the argument validation was performed unnecessarily. Now we can avoid that as well like

int some_function (int arg1, struct StructType *pStructArg)
{
int status = 1;

if (arg1 != valid_value_arg1) {
status = -1; /* argv1 is invalid*/
} else {
if (pStructArg->a != valid_value_a) {
status = -1; /* a is invalid */
} else {
if (pStructArg->b != valid_value_b) {
status = -1;
}
}
}

if (status == 1) {
/* Now do the real job */
...
...
...
}

return status;
}

This is not a real life example and you know how complex real life example would look if we followed above way of writing code.