Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site busch.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!ihnp4!mgnetp!we53!busch!dcm From: dcm@busch.UUCP (Craig Miller) Newsgroups: net.lang.c Subject: Re: break, continue, return, goto (net.religion.c) Message-ID: <516@busch.UUCP> Date: Mon, 4-Nov-85 09:15:51 EST Article-I.D.: busch.516 Posted: Mon Nov 4 09:15:51 1985 Date-Received: Tue, 5-Nov-85 23:13:47 EST References: <771@whuxl.UUCP> Reply-To: dcm@busch.UUCP (Craig Miller) Distribution: net Organization: Anheuser-Busch Companies - St. Louis Missouri Lines: 153 Keywords: In article <771@whuxl.UUCP> mike@whuxl.UUCP (BALDWIN) writes: > /* using continue for error handling in loops */ > for (i = 1; i < argc; i++) { > if ((fp = fopen(argv[i], "r")) == NULL) { > perror(argv[i]); > continue; > } > if (some other reason this arg is bad) { > process(error); > continue; > } > /* code to deal with a good arg */ > while ((c = getc(fp)) != EOF) > munch(c); > } How about: for (i = 1; i < argc; i++) if ((fp = fopen(argv[i], "r")) == NULL) perror(argv[i]); else if (some other reason this arg is bad) process(error); else /* code to deal with a good arg */ while ((c = getc(fp)) != EOF) munch(c); Is this clearer? It's even shorter (I say this for those who think shorter code is always clearer - I don't, but some do...). (BTW, the calls to fclose are missing... :-) Next: > /* using break for ending a complicated search loop */ > for (m = meeble; m < meeble + NMEEBLE; m++) > if (m->glop == forp && m->zip == fweep) { > printf("zeegle %2s", m->yorg); > m->blazzo += IGUAP; > break; > } Becomes: for (m = meeble; m < meeble + NMEEBLE && (m->glop != forp || m->zip != fweep); m++) /* * walk thru the array till we hit the end or * find the right one */ ; /* * did the find the right one? */ if (m < meeble + NMEEBLE) { printf("zeegle %2s", m->yorg); m->blazzo += IGUAP; } Looks like I just made the for statement almost unreadable. Oh well... >/* > * Using multiple returns for error cases. > */ >int >monge(file, index) >char *name; >int index; >{ > if (index < 0 || index >= MAXIDX) { > puts("yikes!"); > return ERR; > } > if (stat(file, &st) < 0) { > perror(file); > return ERR; > } > if (some other reason I can't deal with this) { > process(error); > return error code; > } > /* code to deal with a good call */ > chmod(file, tab[index].mode); > unlink(file); > calculate(newindex); > return newindex; >} How about: { int newindex; if (index < 0 || index >= MAXIDX) { puts("yikes!"); newindex = ERR; } else if (stat(file, &st) < 0) { perror(file); newindex = ERR; } else if (some other reason I can't deal with this) { process(error); newindex = error code; } else { /* code to deal with a good call */ chmod(file, tab[index].mode); unlink(file); calculate(newindex); } return newindex; } Again, this is clearly an "if ; else if ; else" case. >These are clear and obvious uses for break et al., and they reflect >how I *think* about the problems!! E.g., in the first for loop, I >think: "Ok, I have a file to process. Obviously, if I can't open >it, or something weird is wrong with it, then skip it. Once all the >trivial tests for validity are out of the way, go ahead and process it." >Now with the next for loop, the test could be built into the for stmt, >but that would be quite unreadable. I read it thusly: "Go through >the meeble array. When you find a glop and zip match, do something >magic, then get out." > >"Madness takes its toll." Michael Baldwin "Bruce" > {at&t}!whuxl!mike Hmm. I guess we all think about things pretty differently. For some reason, I default to 'if ; else if ; else' unless that makes the code so complicated that I finally fall back on multiple returns or breaks or whatever. (i.e. if I can't open the file, show an error. else if something else happens, show that error. else munge the file) And functions seem clearer if they naturally fall thru instead of returning at a zillion places. The array example is debatable either way, I guess. It all depends on the complexity of what you're testing for. Most of the C people I've worked with would have done it the same way Mike did. But is it really more readable and maintainable? Is it more 'top-down'? Doesn't it seem more top-down for a function to return only at the bottom? Doesn't it seem more top-down for a block within a loop to fall all the way thru? Doesn't anyone else agree that top-down is more readable? (does this belong in net.religion.c ? :-) Craig -- Craig Miller {*}!ihnp4!we53!busch!dcm The Anheuser-Busch Companies; St. Louis, Mo. - Since I'm a consultant here and not an Anheuser-Busch employee, my views (or lack of) are strictly my own.