Op vrijdag 12 april 2002 17:07 schreef drm het volgende:
en waarom dan niet zo :?:
code:
1
2
3
4
5
6
7
| void errorHandler ( code )
{
// en hier de error afhandeling
}
if (errorcode = (functie1(fd) != GELUKT))
errorHandler ( errorcode ); |
omdat de error handler er ook voor moet zorgen dat de functie returnt. en dan kan je wel die return eronder zetten, maar dan kom je dus weer direct op het pad 'je kan er wel omheen lopen, maar goto is gewoonweg veel simpeler in dit soort gevallen'
Op vrijdag 12 april 2002 17:21 schreef dusty het volgende:
Een goede programmeur gebruikt geen GOTO.
(tenzij hij in machine taal aan het programmeren is.)
Iedereen die er anders overdenkt moet maar eens een boek over systeemontwerp lezen.
dankje, ik ben systeemprogrammeur

. Ik
weet dat goto in sommige gevallen handig is. Iedere zealot die dat zonder enig argument dom denkt te kunnen vinden moet mijn bovenstaande stellingen maar eens lezen. Goto is in sommige situaties handig. Proof me wrong

Op vrijdag 12 april 2002 18:00 schreef Creepy het volgende:
Die eerst loopt om het probleem heen?
code:
1
2
3
4
5
6
7
8
9
10
11
12
| static boolean
open_device (char *device)
{
if ((fd = open(device, O_RDWR)) > 0)
if (functie1(fd) = GELUKT)
if (functie2(fd) = GELUKT)
// .. etc
return TRUE;
// error ding hiero... of zelfs in de caller.
return false;
} |
Hoe bedoel je dat precies?
Je moet je dus voorstellen dat er dus een heleboel functies zijn. Sommige returnen iets, anderen niet, sommige returnen dingen die je anders moet interpretten dan anders, etc.
Voorbeeldje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| static boolean
open_device (char *device)
{
if ((fd = open(device, O_RDWR)) <= 0)
goto error;
if (functie1(fd) != GELUKT)
goto error;
functie2(fd);
int returnwaarde;
functie3(fd, &returnwaarde);
if (returnwaarde < 0)
goto error;
//.. etc
[..]
return TRUE;
error:
return false;
} |
(overigens kun je halverwege een functie geen int declareren maar dat vergeten we uit gemaktzucht maar eventjes)
Vergeet niet dat je in een opensource- of bedrijfsomgeving vaak niet in je eentje programmeert. Niet iedereen code exact hetzelfde en dus zijn niet alle APIs identiek qua opbouw. Vooral in C is dat een groot probleem en moet je daar dus op een effectieve manier mee kunnen omgaan.
Op "jouw" manier komt dat er dus ongeveer zo uit te zien:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| static boolean
open_device (char *device)
{
if ((fd = open(device, O_RDWR)) > 0)
{
if (functie1(fd) == GELUKT)
{
functie2(fd);
int returnwaarde;
functie3(fd, &returnwaarde);
if (returnwaarde < 0)
{
//..etc
[..]
return TRUE;
}
}
}
return false;
} |
Je komt steeds verder in de nested situatie terecht, en dat vind ik persoonlijk niet echt 'clean'. En overzichtelijk is het al helemaal niet (denk hierbij aan grotere functies, niet aan de mini-voorbeeldjes die ik hier geef).
[mierenneuken]
ohja, en vergelijkingen in een if is met twee '='jes ipv 1

[/mierenneuken]
Een andere manier die ik soms gebruik om hieruit te komen is een simpele error handler macro definieren, wat overigens al helemaal niet clean is, maar ook vrij simpel werkt en daarnaast ook nog eens per-error-handling mogelijkheden geeft:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| #define handle_error(format, args...) \
{ \
printf(format, ## args); \
goto error; \
}
int fd = 0;
static boolean
open_device (char *device)
{
if ((fd = open(device, O_RDWR)) <= 0)
handle_error("Error opening device: %s\n",
sys_errlist[errno]);
//.. etc.
return TRUE;
error:
//.. allemaal resets/etc.
if (fd > 0)
close(fd);
fd = 0;
return FALSE;
} |
In principe kan je op deze manier zelfs van de goto afkomen, alhoewel je code (de bytecode

) er dus wel groter van zal worden dan.