Article View: net.lang.c
Article #9215Re: C-STYLE (goto?)
From: Chris Torek
Date: Sat, 30 Aug 1986 12:47
Date: Sat, 30 Aug 1986 12:47
80 lines
3273 bytes
3273 bytes
>In article <3253@brl-smoke.ARPA> jeff@isi-vaxa.ARPA writes:
>> setup_step_1;
>> if ( (status = step_1()) == FAILURE )
>> goto abort_operation;
...
>> setup_step_n;
>> if ( (status = step_n()) == FAILURE )
>> goto abort_operation;
>>
>>abort_operation:
>>
>> cleanup();
>> return (status);
>>Now, I know a lot of people detest this because of the use of goto's ....
In article <264@killer.UUCP> toma@killer.UUCP (Tom Armistead) replies:
>There is always the use of setjmp and longjmp to acomplish this task ....
[example deleted]
>This will accomplish the same thing and possibly not affend the goto haters,
>although it is somewhat harder to follow if you are no farmiliar with
>setjmp() and lonjmp().
Alas, longjmp() is nothing more than goto in disguise. Indeed,
this is a far more powerful version of goto than the `plain C'
goto, and should by rights be correspondingly more offensive to
goto haters. In general, when choosing between two existing
primitives, if one is less powerful but does what you need, use
that. When designing primitives, the choice is more difficult:
something that does less is easier to understand, but you may need
too many of those things, making the whole harder to comprehend.
As to a specific solution to the original problem above, I think
there is no `best' answer, at least not without more information.
I happen to like the pointer table method proposed by grt@twitch;
it can be expanded in a useful way for recovery and/or error
explanation:
int dostep1(), dostep2(), dostep3(), dostep4();
int fix1or3(), fix2();
struct step {
char *s_name; /* name of this step */
int (*s_func)(); /* function that implements it */
int (*s_fixup)(); /* repair after error */
} steps[] = {
{ "step1", dostep1, fix1or3 },
{ "step2", dostep2, fix2 },
{ "step3", dostep3, fix1or3 },
{ "step4", dostep4, 0 },
0 /* marks end of table */
};
f()
{
register struct step *s;
int status;
for (s = steps; s->s_func != NULL; s++) {
if ((status = (*s->s_func)()) != SUCCESS) {
if (s->s_fixup == NULL ||
(*s->s_fixup)(status) != SUCCESS) {
fprintf(stderr, "\
Unrecoverable failure in %s, code %d\n",
s->s_name, status;
break;
}
}
}
return (status);
}
There may be cases, however, where a direct-coded state machine
with a `switch' statement would be better; and there may be cases
where the original code runs fastest and/or is clearest (whichever
is more important to the coder/maintainer and user).
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
Technical Details
Message-ID:
<3200@umcp-cs.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!umcp-cs!chrisReferences:
<3253@brl-smoke.ARPA> <264@killer.UUCP>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.lang.c Subject: Re: C-STYLE (goto?) Message-ID: <3200@umcp-cs.UUCP> Date: Sat, 30-Aug-86 08:47:46 EDT Article-I.D.: umcp-cs.3200 Posted: Sat Aug 30 08:47:46 1986 Date-Received: Sat, 30-Aug-86 19:59:05 EDT References: <3253@brl-smoke.ARPA> <264@killer.UUCP> Reply-To: chris@umcp-cs.UUCP (Chris Torek) Organization: University of Maryland, Dept. of Computer Sci. Lines: 80