home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / cplus / 12862 < prev    next >
Encoding:
Text File  |  1992-08-25  |  4.7 KB  |  133 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!haven.umd.edu!darwin.sura.net!mips!mips!munnari.oz.au!cs.mu.OZ.AU!munta.cs.mu.OZ.AU!fjh
  3. From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
  4. Subject: Re: Tiny proposal for named loops.
  5. Message-ID: <9223902.3230@mulga.cs.mu.OZ.AU>
  6. Sender: news@cs.mu.OZ.AU
  7. Organization: Computer Science, University of Melbourne, Australia
  8. References: <aldavi01.714376080@starbase.spd.louisville.edu>     <rmartin.714435942@dirac> <CHUCK.PHILLIPS.92Aug24165034@halley.FtCollinsCO.NCR.COM> <rmartin.714750452@thor>
  9. Date: Tue, 25 Aug 1992 16:54:20 GMT
  10. Lines: 121
  11.  
  12. rmartin@thor.Rational.COM (Bob Martin) writes:
  13.  
  14. >Chuck.Phillips@FtCollinsCO.NCR.COM (Chuck Phillips) writes:
  15. >
  16. >|Two reasons for using goto's (break's, continue's, return's):
  17. >
  18. >|    1. Maintenance: Code what you mean, and mean what you code.  It's
  19. >|       easier on others.  If you *mean* "get out of this loop", use
  20. >|       "break" if you can, goto if you can't.  Restructure your code to
  21. >|       avoid *both* state variables and goto's if you can, but it you
  22. >|       can't, be straightforward.
  23. >
  24. >Consider this:
  25. >
  26. >    while (1)
  27. >    {
  28. >       if (something)
  29. >         break;
  30. >    }
  31. >
  32. >clearly "while (1)" does not fall under your advice to "code what you
  33. >mean".  However, by using a flag, you can put "what you mean" in the
  34. >loop condition.
  35.  
  36. I disagree. If find while(1), or more preferably for(;;), to indicate
  37. quite clearly what the programmer means.
  38.  
  39. If the termination condition for a loop is complex, then
  40. it should be coded as simply as possible - this means using
  41. goto/break/etc - and documented with comments.
  42.  
  43. Don't obfuscate your code with confusing state variables when a simple
  44. "break" will do - just make sure that you EXPLAIN the loop with a
  45. comment!
  46.  
  47. >|Exercise: Try coding a Finite State Machine for arbitrarily length input
  48. >|without using gotos.  
  49.  
  50. I have done that before, no problems.
  51. While we're on the subject of FSM's and gotos, have a look at this code
  52. taken from my Turing machine simulator program. This is another good
  53. example of where gotos are useful. Try rewriting this without gotos!
  54. (Solutions using exceptions don't count - at least, not until my compiler
  55. implements them!)
  56.  
  57. The following code is exactly as I wrote it about 12 months ago.
  58. It's a bit too long for a single function, but without exceptions,
  59. the error handling makes things messy if you split it into multiple
  60. functions. I suppose you could use longjmp to fake them in this case... yuck.
  61.  
  62. istream& operator>> (istream& input, transition_function& t) {
  63.     state s, new_s;
  64.     symbol sym, new_sym;
  65.     dirn dir;
  66.     char c = 0;
  67.  
  68.     // initialize the transition to be completely undefined
  69.     t.initialize();
  70.  
  71.     // add transitions
  72.     while(input) {    // keep searching until file error ...
  73.         input >> s;
  74.         if (input.eof()) break;    // ... or end of file
  75.         input >> c; 
  76.         if (c != ':') goto input_error;
  77.         while (input >> c, c == '{') {
  78.             input >> c;
  79.             switch(c) {
  80.                 case '_': sym = Blank;    break;
  81.                 case 'B': sym = Blank;    break;
  82.                 case 'a': sym = A;        break;
  83.                 case 'b': sym = B;        break;
  84.                 case 'c': sym = C;        break;
  85.                 default : goto input_error;
  86.             }
  87.             input >> c;
  88.             if (c != '/') goto input_error;
  89.             input >> c;
  90.             switch(c) {
  91.                 case '_': new_sym = Blank;    break;
  92.                 case 'B': new_sym = Blank;    break;
  93.                 case 'a': new_sym = A;        break;
  94.                 case 'b': new_sym = B;        break;
  95.                 case 'c': new_sym = C;        break;
  96.                 default : goto input_error;
  97.             }
  98.             input >> c;
  99.             switch(c) {
  100.                 case 'L': dir = Left;    break;
  101.                 case 'R': dir = Right;    break;
  102.                 default : goto input_error;
  103.             }
  104.             input >> new_s;
  105.             input >> c;
  106.             if (c != '}') goto input_error;
  107.  
  108.             // now actually add the transition
  109.  
  110.             if (t.is_defined(s, sym)) {
  111.                 cerr << "Error: duplicate transition (machines must be "
  112.                         "deterministic)\n";
  113.                 return input;
  114.             }
  115.             t.set_trans(s, sym, new_s, new_sym, dir);
  116.         }
  117.         if (input.eof()) break;
  118.  
  119.         // we always get one character to many
  120.         input.putback(c);
  121.     }
  122.     return input;
  123.  
  124. input_error:
  125.     cerr << "Syntax error reading transition function\n";
  126.     return input;
  127. }
  128. -- 
  129. Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
  130. This .signature virus is a self-referential statement that is true - but 
  131. you will only be able to consistently believe it if you copy it to your own
  132. .signature file!
  133.