From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII X-Google-Thread: fac41,9a0ff0bffdf63657 X-Google-Attributes: gidfac41,public X-Google-Thread: 1108a1,9a0ff0bffdf63657 X-Google-Attributes: gid1108a1,public X-Google-Thread: f43e6,9a0ff0bffdf63657 X-Google-Attributes: gidf43e6,public X-Google-Thread: 103376,4b06f8f15f01a568 X-Google-Attributes: gid103376,public From: "Mattias Lundstr�m" Subject: Re: Software landmines (loops) Date: 1998/09/01 Message-ID: <35EB9B91.3FF8583@ehpt.com>#1/1 X-Deja-AN: 386705848 Content-Transfer-Encoding: 8bit References: <902934874.2099.0.nnrp-10.c246a717@news.demon.co.uk> <6r1glm$bvh$1@nnrp1.dejanews.com> <6r9f8h$jtm$1@nnrp1.dejanews.com> <6renh8$ga7$1@nnrp1.dejanews.com> <6rf59b$2ud$1@nnrp1.dejanews.com> <6rfra4$rul$1@nnrp1.dejanews.com> <35DBDD24.D003404D@calfp.co.uk> <6sbuod$fra$1@hirame.wwa.com> <35f51e53.48044143@ <904556531.666222@miso.it.uq.edu.au> <35EAB5B1.1DA1986B@ehpt.com> <6sf1dn$n52$1@hirame.wwa.com> Organization: Ericsson HP X-Priority: 3 (Normal) Content-Type: text/plain; charset=iso-8859-1 Mime-Version: 1.0 Newsgroups: comp.lang.eiffel,comp.object,comp.software-eng,comp.lang.ada Date: 1998-09-01T00:00:00+00:00 List-Id: Robert Martin wrote: > > Mattias Lundstr�m wrote in message <35EAB5B1.1DA1986B@ehpt.com>... > >(Ie The maintenance argument - that the second code version > >becomes harder to read and understand (and thus maintain) - > >since the return statement may well not be obvious if there > >is a lot of other code within the loop. I do not agree > >with this, but it is certainly an argument worth considering. > >IMHO This should be covered by good comments where applicable.) > > It's not so much a matter of being harder to read and understand. Rather it > is that there is no good place to make certain kinds of changes to the code. Ok. I admit. I overlooked this argument... > > For example, let's say that we had to make a change that forced us to open > and close a file that the body of the loop needed to read. Then: > 2. Multiple exits > File* f = fopen(...); > while( ... ) { > ... > if( ... ){ > fclose(f); > return NOT_OK; > } > } > fclose(f); > return OK; Obviously you should NOT write code like this (for the reasons you state). If the needs for cleanup continue to grow this will become unmanageble very quickly. Especially if we have a lot of exits where we need to duplicate code. If you need cleanup before leaving the function you would need to change the original loop layout. Perhaps to: File* f = fopen(...); while( ... ) { ... if( ... ){ retval = NOT_OK; goto leave_loop; } } leave_loop: fclose(f); return retval; where I have used goto instead of break mostly to annoy ;-) I still think that a multi-exit solution like this is better then juggling flags in many cases. (Question: Is this still a multi-exit according to your defintions. It clearly is is you choose to analyse the control flow and see the goto as not a part of the loop predicate.) In this case it would be more elegant to instead use a file class that automatically closes the file when going out of scope, but this may be infeasible in some general cases. Eg A. We are using a GC language and can not know when the object will be cleaned up. B. There may be a need for error handling in the cleanup part of the code. We do NOT want to throw exceptions from the destructors. > Clearly solution 1 is easier to deal with than solution 2. Solution 1 In fact this change almost demands for the rewrite of solution 2. - Mattias