Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!houxm!whuxl!whuxlm!akgua!gatech!seismo!brl-adm!brl-smoke!smoke!HARGED%ti-eg.csnet@CSNET-RELAY.ARPA From: HARGED%ti-eg.csnet@CSNET-RELAY.ARPA Newsgroups: net.lang.c Subject: goto jumps into loops Message-ID: <156@brl-smoke.ARPA> Date: Sun, 20-Apr-86 21:12:07 EST Article-I.D.: brl-smok.156 Posted: Sun Apr 20 21:12:07 1986 Date-Received: Thu, 24-Apr-86 06:16:33 EST Sender: news@brl-smoke.ARPA Lines: 106 To Dave Harmon: I've got a couple of comments about the code you posted to the net last week. I wish you had compiled and run the code you posted. There are some vestigal remnants of its previous incarnation as a Pascal program that keep it from compiling and running correctly. Listed below is the version I used in my tests. /*************************************************************************/ static int wrtlist (list) set list; { unsigned int i=0; do { putchar (' '); do { if (i == MAX) /* please note equality operator */ return (0); else i++; } while (!in (i, list)); /* both looping forms iterate */ /* when the condition is TRUE */ cross: printf ("%d", i); if (i == MAX) return (0); else i++; } while (!in (i, list)); putchar ('-'); while ((i < MAX) && (in (i+1, list))) i++; goto cross; } /*************************************************************************/ Below is a version I came up with that is structured; i.e. all control constructs are single-entry, single-exit. Please note the absence of boolean state variables. /*************************************************************************/ static void wrtlist2 (list) set list; { /* Scan the set represented by list, printing the members that * are present. If two or more consecutive members are present * then print them as a range represented by X-Y where X is * the first member and Y is the last member of the range. */ unsigned int i=0; while (i < MAX) { /* scan whole set */ if (in (i++, list)) { /* matching member found */ printf ("%d", i-1); /* print first member */ if (in (i, list)) { /* we have a range */ putchar ('-'); /* range seperator */ while (in (++i, list)); /* skip internal members */ printf ("%d", i-1); /* print last member */ } i++; /* avoid redundant check */ putchar (' '); } } } /*************************************************************************/ Now for the comparison: using small-model Lattice C, v 2.14, on a TI-PC, your routine compiled to a size of 0xCB bytes, mine 0xCC bytes. While I didn't gather execution times, an informal analysis indicates that both routines are a few assignments, comparisons, three calls to in (), and calls to putchar and printf. Since the number of calls made to putchar and printf are equl for both routines, they will be ignored. It appears that the bulk of the remaining execution time will involve the calls to in (). Therefore counting the number of calls to in () will give us a ballpark estimate of the execution time differences. For a 100 element set with the following members present [ 0 2 5-6 10-12 16-19 22-27 99 ] your routine called in () 104 times, mine 101. I call the two routines even in terms of size and execution speed. Beyond this, I think my version has some added benifits. My version can recognize member 0 of the set. I think my version is more intuitive; it models the process a human would follow when doing the same thing. And while I took advantage of the prefix/postfix ++ operators, the algorithm I followed is very general (it doesn't require multiple return statements or the ability to jump into a loop). Please don't confuse me with a structured programming purist. I have no problem using the goto in its many forms (i.e., at least single-entry, mulitiple-exit control constucts) when the situation requires it. Just remember that its use can cause problems for code optimizers, both human and machine. regards, Richard Hargrove CSNET: harged@ti-eg Texas Instruments, Inc. ARPA: harged%ti-eg@csnet-relay ----------------------- -------------------------------