goto to switch labels

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

Can you goto switch labels?

int i=0; /* arbitrary */

switch( i ) {
case 0:
if( !some_validity_check() ) {
goto error; /* could be default as well */
}
/* proceed normally */
break;
case 1:
if( !some_other_validity_check() ) {
goto error;
}
/* proceed normally */
break;
case 2:
if( !yet_another_validity_check() ) {
goto error;
}
/* proceed normally */
break;
error:
default: /* invalid input */
handle_error();
exit( EXIT_FAILURE ); /* or something */
}
/* proceed normally */

If this is possible, is it a reasonable choice stylistically, to avoid
re-coding the error handling code?
 
C

Chris Torek

Can you goto switch labels?

If you mean, is there some syntax by which you could eliminate
the separate label "error" here, then "no". On the other hand,
if you mean is it OK to write "goto error" inside the switch,
and then include the parts I left below, then the answer is
"yes":
switch( i ) {
[various cases that sometimes "goto error"]
break;
error:
default: /* invalid input */
handle_error();
exit( EXIT_FAILURE ); /* or something */
}
/* proceed normally */

If this is possible, is it a reasonable choice stylistically, to avoid
re-coding the error handling code?

I tend to dislike it myself. You could recode it as:

void f(void) {
...
switch (i) {
case ...
... various cases that sometimes "goto error" ...
break;
default:
goto error;
}
... /* proceed normally */
return;

error:
handle_error();
exit(EXIT_FAILURE); /* or something */
}

and I would not object (or at least, would object far less :) ).
 
E

Eric Sosman

Christopher said:
Can you goto switch labels?

int i=0; /* arbitrary */

switch( i ) {
case 0:
if( !some_validity_check() ) {
goto error; /* could be default as well */
}
/* proceed normally */
break;
case 1:
if( !some_other_validity_check() ) {
goto error;
}
/* proceed normally */
break;
case 2:
if( !yet_another_validity_check() ) {
goto error;
}
/* proceed normally */
break;
error:
default: /* invalid input */
handle_error();
exit( EXIT_FAILURE ); /* or something */
}
/* proceed normally */

If this is possible, is it a reasonable choice stylistically, to avoid
re-coding the error handling code?

It's possible, AFAIK, but it's ugly: burying the
error target inside a `switch' case is a good way to
hide it (for extra obfuscation, label it `defualt:').

Here's a rearrangement that (I think) more readable:

switch (i) {
case 1:
if (! valid1())
goto error;
stuff1();
break;
case 2:
if (! valid2())
goto error;
stuff2();
break;
...
default:
goto error;
}
...
return HOORAY_IT_FINALLY_WORKED;

error:
handle_error();

(Anyone who finds the extra `goto' "inefficient"
is invited to ponder the payoff of optimizing the error
path, especially if the error is fatal.)
 
D

Dave

Eric said:
Christopher Benson-Manica wrote:

Here's a rearrangement that (I think) more readable:

switch (i) {
case 1:
if (! valid1())
goto error;
stuff1();
break;
case 2:
if (! valid2())
goto error;
stuff2();
break;
...
default:
goto error;
}
...
return HOORAY_IT_FINALLY_WORKED;

error:
handle_error();

(Anyone who finds the extra `goto' "inefficient"
is invited to ponder the payoff of optimizing the error
path, especially if the error is fatal.)

This would be my preference; it doesn't use a goto or negative logic,
and by specifying the value for err you could pass the reason for the
error into handl_error() if you so desired, so that the user would get a
specific error message rather than a general one that could mean
anything (which I find in my programs is more useful, even if I just
output the error number, at least I can then look in the code):

err=0;

switch (i) {
case 1:
if (valid1())
stuff1();
else
err=1;
break;

case 2:
if (valid2())
stuff2();
else
err=2;
break;

default:
err=3;
break;
}

if (err)
handle_error(err);

Dave.
 
M

Michael Wojcik

switch( i ) {
case 0:
if( !some_validity_check() ) {
goto error; /* could be default as well */
}
/* proceed normally */
break;
error:
default: /* invalid input */
handle_error();
exit( EXIT_FAILURE ); /* or something */
}

Chris and Eric have already weighed in against this practice, on
style grounds, but I thought I'd mention that I find it perfectly
reasonable, if you added a bit more vertical whitespace to make it
more readable. I find it neither ugly nor error-prone.
 
M

Mabden

Michael Wojcik said:
Chris and Eric have already weighed in against this practice, on
style grounds, but I thought I'd mention that I find it perfectly
reasonable, if you added a bit more vertical whitespace to make it
more readable. I find it neither ugly nor error-prone.

It is probably actually better than the "fall thru" technique, as it is
more explicit. However I would just set a flag and check it at the end
of the switch.

error_flag = NO_ERR;
switch (i) {
case OOPS:
if( !some_validity_check() )
error_flag = ERR_OOPS;
break;
}
if (error_flag != NO_ERR)
handle_errors(error_flag);
return error_flag;
 
C

Christopher Benson-Manica

Mabden said:
It is probably actually better than the "fall thru" technique, as it is
more explicit. However I would just set a flag and check it at the end
of the switch.

I could do that, of course, but something about it strikes me as
inelegant... YMMV :)
 
M

Mabden

Christopher Benson-Manica said:
I could do that, of course, but something about it strikes me as
inelegant... YMMV :)

Another thought: How often is the "Default:" case going to a good place
to do error processing? Generally, default a catch-all for an unknown
switch item and needs a message like "Bad input detected, get a new
programmer" but an error produced by a valid switch item will usually
need a different kind of message like "File does not exist, I can't do
what you want".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top