Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.csd.uwm.edu!cs.utexas.edu!uunet!twwells!bill From: bill@twwells.com (T. William Wells) Newsgroups: comp.lang.c Subject: Re: Oh nooo! (gotos) Message-ID: <1989Sep8.070123.4416@twwells.com> Date: 8 Sep 89 07:01:23 GMT References: <7598@goofy.megatest.UUCP> <12793@pur-ee.UUCP> Organization: None, Ft. Lauderdale, FL Lines: 88 : while(rule = (Rule*)Queue_iter_next(&rule_iter)) { : : while(rsym = (Symbol*)Queue_iter_next(&rsym_iter)) { : switch (derives(rsym)) { : case derives_nothing: : goto next_rule; : .... : } : } : : next_rule: continue; : : } Look Ma, no goto! while(rule = (Rule*)Queue_iter_next(&rule_iter)) { while(rsym = (Symbol*)Queue_iter_next(&rsym_iter)) { switch (derives(rsym)) { case derives_nothing: break; .... (cases that want to loop use continue) } break; } } I use this one all the time. And I do mean all the time. This is an example of how I write the argument parser for my programs: init_program(argv[0]); list_ids_only = 0; all_users = 0; user_name = 0; sys_name = 0; kill_id = 0; interactive_kill = 0; show_machines = 0; show_procs = 0; show_queue = 0; no_kill = 0; opterr = 0; while (1) { switch (getopt(argc, argv, "aF:hik:Kmpqr:s:u:x:X")) { case EOF: break; default: usage("illegal option or missing option argument"); case 'a': all_users = 1; continue; case 'F': set_directory(optarg); continue; case 'h': uustat_help(); case 'i': list_ids_only = 1; continue; case 'k': kill_id = optarg; func = my_unlink; continue; case 'K': interactive_kill = 1; continue; case 'm': show_machines = 1; continue; case 'p': show_procs = 1; continue; case 'q': show_queue = 1; continue; case 'r': kill_id = optarg; func = my_touch; continue; case 's': sys_name = optarg; continue; case 'u': user_name = optarg; continue; case 'x': Debug_level = atoi(optarg); continue; case 'X': no_kill = 1; continue; } break; } And here is how I code state machines: state = ST_INIT; while (1) { ... get inpot switch (state) { case ST_INIT: ... continue for the next state ... break to exit the state machine ... } break; } Yes, I know all the limitations of this method. And yes, I have already though of all the arguments for why one shouldn't do this. I compared them with all the problems of using gotos and found this to be preferable. After seven years of C programming, I still haven't used a goto. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com