Article View: comp.lang.misc
Article #4395Re: GOTO controversy
From: John Noland
Date: Tue, 12 Mar 1996 00:32
Date: Tue, 12 Mar 1996 00:32
159 lines
5655 bytes
5655 bytes
In article <DnwCxp.84C@clw.cs.man.ac.uk>, chl@clw.cs.man.ac.uk says...
>
>In <4hl8mt$4po@newshost.cyberramp.net> sinan@cyberramp.net (John Noland) writes:
>
>>>Robert C Shields (rcshlds@mailserv.mta.ca) wrote:
>
>>The above is NOT an example of a good use for the goto statement.
>
>Well that is what I thougut when I first saw the example, and I was about to
>dash off an article like you have done. But then I looked again and saw
>*exactly* what it was doing.
>
>So if you believe there is a better way, please can we see it?
>
I saw *exactly* what it was doing.
I only have one problem with this example. It looks to me like he's trying to avoid
duplicate code by using goto's. Yet, it seems to me that in the spot where he says:
/* Do some stuff here */
return TRUE; /* We did okay */
really looks like this:
/* Do some stuff here */
NOTE>/* including this? */
NOTE> free(ptr);
NOTE> DosCloseMutexSem(hmtx);
NOTE> DosCloseEventSem(hev3);
NOTE> DosCloseEventSem(hev2);
NOTE> DosCloseEventSem(hev1);
return TRUE; /* We did okay */
so the obvious change I would make is this:
HEV hev1, hev2, hev3; /* Event semaphores */
HMTX hmtx; /* Mutex semaphore */
void *ptr;
int retval; /* I'm assuming he's returning an int */
/* There should be explicit initialization of all locals here */
retval = TRUE;
if (!DosCreateEventSem(0, &hev1, 0, FALSE))
retval = FALSE;
goto hev1_failed
if (!DosCreateEventSem(0, &hev2, 0, FALSE))
retval = FALSE;
goto hev2_failed;
if (!DosCreateEventSem(0, &hev3, 0, FALSE))
retval = FALSE;
goto hev3_failed;
if (!DosCreateMutexSem(0, &hmtx, 0, FALSE))
retval = FALSE;
goto hmtx_failed;
if ((ptr = malloc(SOME_SIZE)) == NULL)
retval = FALSE;
goto malloc_failed;
/* Do some stuff here */
free(ptr);
malloc_failed:
DosCloseMutexSem(hmtx);
hmtx_failed:
DosCloseEventSem(hev3);
hev3_failed:
DosCloseEventSem(hev2);
hev2_failed:
DosCloseEventSem(hev1);
hev1_failed:
return retval;
To code a proper alternative to the goto's, I would really require some more
information. I'm not familiar w/ this particular semaphore implementation,
so I have to make some assumptions. I assume HEV and HMTX are structures
that contain something similar to the UNIX implementation, semaphore value
(semval), the process id of the last process to use the semphore(sempid),
etc... In the implementations I've seen (and I'm not terribly knowledgeable
about IPC mechanisms in general), there is a function called semget(). I don't
know much about this, but I do know it returns a semaphore ID. I can't tell
if that's what DosCreateXXXXSem() is doing or not. The original author treats
it as a boolean. Something like the following would work to eliminate the goto's,
but, it would be difficult to prove this method's superiority in this instance.
typedef struct {
int hev_return;
HEV hev_struct;
} HEV_SEM;
typedef struct {
int hmtx_return;
HMTX hmtx_struct;
} HMTX_SEM;
int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
int some_function(void) {
int retval;
HEV_SEM hev1, hev2, hev3; /* Event semaphores */
HMTX_SEM hmtx; /* Mutex semaphore */
void *ptr;
retval = TRUE;
memset((HEV_SEM *)&hev1, 0, sizeof (HEV_SEM));
memset((HEV_SEM *)&hev2, 0, sizeof (HEV_SEM));
memset((HEV_SEM *)&hev3, 0, sizeof (HEV_SEM));
memset((HMTX_SEM *)&hmtx, 0, sizeof (HMTX_SEM));
if (!alloc_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr)) {
free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
return FALSE;
}
/* Do some stuff here */
free_fn_resources(&hev1, &hev2, &hev3, &hmtx, ptr);
return TRUE;
}
int alloc_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr) {
if ((hev1->hev_return = DosCreateEventSem(0, &hev1->hev_struct, 0, FALSE)) == 0)
return FALSE;
if ((hev2->hev_return = DosCreateEventSem(0, &hev2->hev_struct, 0, FALSE)) == 0)
return FALSE;
if ((hev3->hev_return = DosCreateEventSem(0, &hev3->hev_struct, 0, FALSE)) == 0)
return FALSE;
if ((hmtx->hmtx_return = DosCreateMutexSem(0, &hmtx->hev_struct, 0, FALSE)) == 0)
return FALSE;
if ((ptr = malloc(SOME_SIZE)) == NULL)
return FALSE;
return TRUE;
}
void free_fn_resources(HEV_SEM *hev1, HEV_SEM *hev2, HEV_SEM *hev3, HMTX_SEM *hmtx, void *ptr);
if (ptr != NULL)
free(ptr);
if (hmtx->hmtx_return != 0)
DosCloseMutexSem(hmtx->hmtx_struct);
if (hev1->hev_return != 0)
DosCloseEventSem(hev3->hev_struct);
if (hev2->hev_return != 0)
DosCloseEventSem(hev2->hev_struct);
if (hev3->hev_return != 0)
DosCloseEventSem(hev1->hev_struct);
}
If I made any mistakes here, I apologize. This code is off the top of my head.
-John
Technical Details
Message-ID:
<4i2gmv$ect@newshost.cyberramp.net>Path:
arc1-ca.pugleaf.net!newshost.cyberramp.net!newsReferences:
<rcshlds.1.000A6705@mailserv.mta.ca> <Dn8pJ8.nqs@emi.net> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <DnwCxp.84C@clw.cs.man.ac.uk>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!newshost.cyberramp.net!news From: sinan@cyberramp.net (John Noland) Newsgroups: comp.lang.misc,comp.lang.c,comp.lang.pl1 Subject: Re: GOTO controversy Date: 12 Mar 1996 00:32:31 GMT Organization: Prose Software Message-ID: <4i2gmv$ect@newshost.cyberramp.net> References: <rcshlds.1.000A6705@mailserv.mta.ca> <Dn8pJ8.nqs@emi.net> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <DnwCxp.84C@clw.cs.man.ac.uk> NNTP-Posting-Host: ramp1-12.cyberramp.net X-Newsreader: WinVN 0.99.5