Mattias Lundstr�m wrote in message <35EB9B91.3FF8583@ehpt.com>... >Robert Martin wrote: > >> 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; > This is roughly equivalent to the 'finally' solution in another post. And I'll use the same argument. char* p = malloc(80); if (!p) goto error_exit; File* f = fopen(...); if (!f) goto error_exit; while (...) { if (horrible_error) goto error_exit; } fclose(f); free(p) return OK; error_exit: if (p) free(p); if (f) fclose(f); return NOT_OK; } The redundant resource cleanup, and the checks made in the error_exit section are pretty ugly. And this ugliness will only grow and become more contorted over time. Also, it is not guaranteed that all resources will have check functions, forcing the use of flags (which is all p and f are used for in error_exit) in order to determine when it is safe to release such a resource. Single-entry/single-exit (se/se) structures always have appropriate places for acuiring and freeing resources. The state of the algorithm is encoded into the structure. Multiple exits, gotos, finally clauses, destructures, etc, all *lose* state information. Once they are invoked, the previous state of the algorithm can only be recaptured by investigating the data and within the algorithm. This means flags that cover the entire scope of the algorithm must be maintained so that the error recovery code can determine what to do. Now certainly it is easier to write the functions with multiple exits. And if the functions never change, then you have won; and using a structured programming approach would be a net loss. However, functions generally don't remain the same. Most of the time they <> (remember Kahn talking about how his "pets" enter through your ear and live inside your brain? "Later", he said, " as they <>...") Functions that have not been built using structured programming can degrade pretty badly when they <>. The decision to use multiple exists (other than exceptions) is a short term decision that will probably yeild short term benefits. But in the long term the decision has the potential to cause significant pain. Personally, I have experienced enough of that sort of pain, so I am pretty careful about se/se. Robert C. Martin | Design Consulting | Training courses offered: Object Mentor | rmartin@oma.com | Object Oriented Design 14619 N Somerset Cr | Tel: (800) 338-6716 | C++ Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com "One of the great commandments of science is: 'Mistrust arguments from authority.'" -- Carl Sagan