467,228 Members | 1,377 Online

# How not to abuse a "for loop": examples?

 At the page: http://www.strath.ac.uk/IT/Docs/Ccou...00000000000000 or http://tinyurl.com/4ptzs the author warns: "The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? I'm googling for c misuse "for loop" c abuse "for loop" with little luck. I'd like to see what *not* to do :) Toby Nov 14 '05 #1
• viewed: 4113
Share:
32 Replies
 On 9 Aug 2004, Toby Newman wrote: the author warns: "The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? I'm googling for c misuse "for loop" c abuse "for loop" with little luck. I'd like to see what *not* to do :) for (a(), b(), c(), d(), e(), f(), g(); h(), i(), j(), k(), l(), m(), n(), o(), p(); q(), r(), s(), t(), u(), v(), w(), x(), y(), z()) ; Tak-Shing Nov 14 '05 #2
 "Toby Newman" wrote in message news:25**************************@posting.google.c om... "The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? I'm googling for c misuse "for loop" c abuse "for loop" with little luck. I'd like to see what *not* to do :) for (i = 0; i < 100; i += (i == 98) ? -97 : 2) for (; *++argv && (fp = fopen(*argv, "rb")) && fread(buffer, 10, 10, fp) == 10 && fclose(fp) != EOF; ) Although, I'm guilty of both. ;) -- Peter Nov 14 '05 #3
 Toby Newman wrote: At the page: http://www.strath.ac.uk/IT/Docs/Ccou...00000000000000 or http://tinyurl.com/4ptzs the author warns: "The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? I'm googling for c misuse "for loop" c abuse "for loop" with little luck. I'd like to see what *not* to do :) Toby for (i = 0; i < 100; ++i) { --i; } float j; for (j = 0.0; j != 10.0; j += 0.1) { } unsigned int m; for (m = 9; m > 0; m -= 2) { } -- Thomas Matthews C++ newsgroup welcome message: http://www.slack.net/~shiva/welcome.txt C++ Faq: http://www.parashift.com/c++-faq-lite C Faq: http://www.eskimo.com/~scs/c-faq/top.html alt.comp.lang.learn.c-c++ faq: http://www.comeaucomputing.com/learn/faq/ Other sites: http://www.josuttis.com -- C++ STL Library book Nov 14 '05 #4
 On Mon, 9 Aug 2004, Toby Newman wrote: At the page: http://www.strath.ac.uk/IT/Docs/Ccou...00000000000000 or http://tinyurl.com/4ptzs the author warns: "The for loop is frequently used, usually where the loop will be traversed a fixed number of times. It is very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? I'm googling for c misuse "for loop" c abuse "for loop" with little luck. I'd like to see what *not* to do :) There is nothing you can do with the for loop that you cannot do with the while loop. For some bizzare reason, people tend to abuse the comma operator in a for loop but not in a while loop. The for loop has three sections: for(init; check; incr) The init section is where you initialize variables used in the for loop. A little abuse happens here. People initialize a number of variables here when they could have been initialized before the loop. I like to do this if the variables are relative to the loop. If I initialize them at the top of scope the initialization might not be visible while I step through the for loop. The big abuse is in the check section. Here you should be checking to see if the for loop should exit of not. Some times programmers will stick a number of statements that could just as easily fit in the body of the loop into this section. This often makes for a hard to read bit of code. Another place for abuse is the incr section. This is the section that you should be incrementing something. If you use a for loop for stepping through a known number of iterations then this section should just be incrementing the counter used to keep track of the iterations. There are no hard and fast rules on this. I often see: while((c = getchar()) != EOF) { /* code */ } getting converted to: for(; (c = getchar()) != EOF; /* code */); It is all a matter of coding conventions or style. -- Send e-mail to: darrell at cs dot toronto dot edu Don't send e-mail to vi************@whitehouse.gov Nov 14 '05 #5
 In article <25**************************@posting.google.com >, Toby Newman wrote:At the page:http://www.strath.ac.uk/IT/Docs/Ccou...00000000000000orhttp://tinyurl.com/4ptzsthe author warns:"The for loop is frequently used, usually where the loop will betraversed a fixed number of times. It is very flexible, and noviceprogrammers should take care not to abuse the power it offers."Could someone give an example of this abuse? I'm googling forc misuse "for loop"c abuse "for loop"with little luck.I'd like to see what *not* to do :) -------- for(in=fopen(filename,"r");in&&fgets(buf,sizeof buf,in);) { /*do stuff with this line of the file*/ } -------- /*i is unsigned*/ for(i=1;i;i*=2) { /*do stuff with this power of 2*/ } /*we fall out when we hit max(i)+1 and the unsigned arithmetic wraps back around to 0 */ -------- A favorite of mine, that falls under "uncommon" but not "abuse", is: -------- for(curr=head;curr;curr=curr->next) { /*Do stuff with this list node*/ } -------- to walk through a linked list. dave -- Dave Vandervies dj******@csclub.uwaterloo.ca [This] is otherwise known as 'learning by experience'. I don't often come across people who publicly state they're not interested in that. --Arthur van der Harg in the scary devil monastery Nov 14 '05 #6
 Dave Vandervies wrote: A favorite of mine, that falls under "uncommon" but not "abuse", is: -------- for(curr=head;curr;curr=curr->next) { /*Do stuff with this list node*/ } -------- to walk through a linked list. Is that really so uncommon? It seems like the natural way to traverse a linked list. (Except that I would explicitly test for curr != NULL, since curr is not a boolean value. But that's also a matter of taste). Christian Nov 14 '05 #7
 "Christian Kandeler" wrote in message news:2n************@uni-berlin.de... Dave Vandervies wrote: A favorite of mine, that falls under "uncommon" but not "abuse", is: -------- for(curr=head;curr;curr=curr->next) { /*Do stuff with this list node*/ } -------- to walk through a linked list. Is that really so uncommon? It seems like the natural way to traverse a linked list. (Except that I would explicitly test for curr != NULL, since curr is not a boolean value. But that's also a matter of taste). curr != NULL or curr != 0? I'm confused now, after the Null Pointer thread... "Keith!!! Where are you?!!" -- Mabden Nov 14 '05 #8
 Mabden wrote: "Christian Kandeler" wrote in message news:2n************@uni-berlin.de... Dave Vandervies wrote: for(curr=head;curr;curr=curr->next) (Except that I would explicitly test for curr != NULL, since curr is not a boolean value. But that's also a matter of taste). curr != NULL or curr != 0? Since the point of writing curr != NULL or curr != 0 instead of just (;curr;) is to enhance legibility, I think it makes sense to write curr != NULL When I read (curr != NULL), that tells me that the author thought that curr was a pointer, when he wrote the code. Nov 14 '05 #9
 go****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>... "The for loop is ... very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? ... I'd like to see what *not* to do :) http://tinyurl.com/2452h/wnim.htm (scroll about half way down.) Hope this helps, James Nov 14 '05 #10
 James Dow Allen wrote: go****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>..."The for loop is ... very flexible, and noviceprogrammers should take care not to abuse the power it offers."Could someone give an example of this abuse? ...I'd like to see what *not* to do :) http://tinyurl.com/2452h/wnim.htm (scroll about half way down.) Hope this helps, James You win. ;-) Why did you write it like that? boa Nov 14 '05 #11
 On 9 Aug 2004 01:03:16 -0700, go****@asktoby.com (Toby Newman) wrote: At the page:http://www.strath.ac.uk/IT/Docs/Ccou...00000000000000orhttp://tinyurl.com/4ptzsthe author warns:"The for loop is frequently used, usually where the loop will betraversed a fixed number of times. It is very flexible, and noviceprogrammers should take care not to abuse the power it offers."Could someone give an example of this abuse? I'm googling forc misuse "for loop"c abuse "for loop"with little luck.I'd like to see what *not* to do :)Toby Something like this? for(i=0; i<1000; ++i) for(j=0; j<1000; ++j) for(k=0; k<1000; ++k) for(ii=0; ii<1000; ++ii) for(jj=0; jj<1000; ++jj) for(kk=0; kk<1000; ++kk) for(z=0; z<1000; ++z) f(i,j,k,ii, jj, kk, z); Nov 14 '05 #12
 # Thomas Matthews for (i = 0; i < 100; ++i) { --i; } Gets the program stuck in a loop. I guess you could do the same with while(1) {} float j; for (j = 0.0; j != 10.0; j += 0.1) { } Keeps the program occupied for a little while. I guess better to time the pause some other way, more accurately and less dependant upon processor speed. unsigned int m; for (m = 9; m > 0; m -= 2) { } I guess the problem with this one is that m being an unsigned integer will cause problems when you perform 9 - 2 - 2 - 2 - 2 - 2... and never get to be lessthan or equal to 0, so the loop goes on forever. -- Toby Nov 14 '05 #13
 # James Dow Allen go****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>... "The for loop is ... very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? ... I'd like to see what *not* to do :) http://tinyurl.com/2452h/wnim.htm (scroll about half way down.) Hope this helps, James This bit? for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; He's nesting them. That's frowned upon? -- Toby Nov 14 '05 #14
 Toby Newman wrote: # James Dow Allengo****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>..."The for loop is ... very flexible, and noviceprogrammers should take care not to abuse the power it offers."Could someone give an example of this abuse? ...I'd like to see what *not* to do :)http://tinyurl.com/2452h/wnim.htm(scroll about half way down.)Hope this helps,James This bit? for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; He's nesting them. That's frowned upon? Did you miss the definition of the NFOR macro? Worry not, here's a copy. #define NFOR(N) \ for (psize[N] = 0; \ psize[N] <= psize[N-1] \ && (N > NROW - 2 || N == NROW - 2 && \ (winbits = (unsigned short *)(*grow[N-1]++ \ = calloc(1, WID * sizeof (unsigned short)))) \ || (grow[N] = (Node *)(*grow[N-1]++ \ = calloc(1, ((unsigned)psize[N]+1) \ * sizeof (Node))))); psize[N]++, plast = N) And note how it is used: /* * After the foregoing preliminaries, a brief nested * loop suffices to solve every position. */ NFOR(1) NFOR(2) NFOR(3) NFOR(4) NFOR(5) NFOR(6) NFOR(7) NFOR(8) NFOR(9) NFOR(10) NFOR(11) NFOR(12) { if (plast) { for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; winbits[INDX(10)] |= 1 << INDX(11); contin_3: ; } } I tried to preprocess (gcc -E -P) and indent it to be able to post it, but that wasn't possible with 14 nested for loops and a couple of if-tests as well. Clearly a winner, IMHO boa@home Nov 14 '05 #15
 # boa Toby Newman wrote: # James Dow Allengo****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>..."The for loop is ... very flexible, and noviceprogrammers should take care not to abuse the power it offers."Could someone give an example of this abuse? ...I'd like to see what *not* to do :)http://tinyurl.com/2452h/wnim.htm(scroll about half way down.)Hope this helps,James This bit? for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; He's nesting them. That's frowned upon? Did you miss the definition of the NFOR macro? Worry not, here's a copy. #define NFOR(N) \ for (psize[N] = 0; \ psize[N] <= psize[N-1] \ && (N > NROW - 2 || N == NROW - 2 && \ (winbits = (unsigned short *)(*grow[N-1]++ \ = calloc(1, WID * sizeof (unsigned short)))) \ || (grow[N] = (Node *)(*grow[N-1]++ \ = calloc(1, ((unsigned)psize[N]+1) \ * sizeof (Node))))); psize[N]++, plast = N) And note how it is used: /* * After the foregoing preliminaries, a brief nested * loop suffices to solve every position. */ NFOR(1) NFOR(2) NFOR(3) NFOR(4) NFOR(5) NFOR(6) NFOR(7) NFOR(8) NFOR(9) NFOR(10) NFOR(11) NFOR(12) { if (plast) { for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; winbits[INDX(10)] |= 1 << INDX(11); contin_3: ; } } I tried to preprocess (gcc -E -P) and indent it to be able to post it, but that wasn't possible with 14 nested for loops and a couple of if-tests as well. Clearly a winner, IMHO boa@home So, do I understand correctly that the extreme nesting of for loops is bad behaviour because it makes the code hard to read and hard for pre- processors to parse? -- Toby Nov 14 '05 #16
 Toby Newman wrote: # boaToby Newman wrote:# James Dow Allen go****@asktoby.com (Toby Newman) wrote in message news:<25**************************@posting.google. com>... >"The for loop is ... very flexible, and novice>programmers should take care not to abuse the power it offers.">>Could someone give an example of this abuse? ...>I'd like to see what *not* to do :)http://tinyurl.com/2452h/wnim.htm(scroll about half way down.)Hope this helps,James This bit? for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3;He's nesting them. That's frowned upon?Did you miss the definition of the NFOR macro? Worry not, here's a copy.#define NFOR(N) \ for (psize[N] = 0; \ psize[N] <= psize[N-1] \ && (N > NROW - 2 || N == NROW - 2 && \ (winbits = (unsigned short *)(*grow[N-1]++ \ = calloc(1, WID * sizeof (unsigned short)))) \ || (grow[N] = (Node *)(*grow[N-1]++ \ = calloc(1, ((unsigned)psize[N]+1) \ * sizeof (Node))))); psize[N]++, plast = N) And note how it is used: /* * After the foregoing preliminaries, a brief nested * loop suffices to solve every position. */ NFOR(1) NFOR(2) NFOR(3) NFOR(4) NFOR(5) NFOR(6) NFOR(7) NFOR(8) NFOR(9) NFOR(10) NFOR(11) NFOR(12) { if (plast) { for (numpile = 1; numpile <= plast; numpile++) for (numrem = 1; numrem <= psize[plast]; numrem++) if (WINNER) goto contin_3; winbits[INDX(10)] |= 1 << INDX(11); contin_3: ; } }I tried to preprocess (gcc -E -P) and indent it to be able to post it,but that wasn't possible with 14 nested for loops and a couple ofif-tests as well. Clearly a winner, IMHO boa@home So, do I understand correctly that the extreme nesting of for loops is bad behaviour because it makes the code hard to read IMO, yes. and hard for pre-processors to parse? That was probably just bad english by me. The preprocessor had no problems processing the code at all, but the preprocessed code was unreadable (at least to me). boa@home Nov 14 '05 #17
 In article <2n************@uni-berlin.de>, Christian Kandeler wrote:Dave Vandervies wrote: A favorite of mine, that falls under "uncommon" but not "abuse", is: -------- for(curr=head;curr;curr=curr->next) { /*Do stuff with this list node*/ } -------- to walk through a linked list.Is that really so uncommon? It seems like the natural way to traverse alinked list. Most linked list traversals I've seen use while instead: -------- curr=head; while(curr) { /*do stuff*/ curr=curr->next; } -------- I suspect that this may be a result of most languages having less general for loops that are only suitable for counting, so most programmers don't come up with it on their own. (I don't think I came up with it on my own, but I have no idea where I first encountered it.) dave -- Dave Vandervies dj******@csclub.uwaterloo.ca If depends on the compiler and the hardware. But in general, the first will be incredibly fast while the other will be incredibly fast. --Gergo Barany in comp.lang.c Nov 14 '05 #18
 On Tue, 10 Aug 2004, Toby Newman wrote: # Thomas Matthews for (i = 0; i < 100; ++i) { --i; } Gets the program stuck in a loop. I guess you could do the same with while(1) {} Correct. However, I'm not sure if Thomas was also meaning to refer to the more common but IMHO equally abusive for (i=0; i < 100; ++i) { if (foo(i)) { /* You know what? Let's process this |i| again. */ --i; continue; } } However, just because it's abusive doesn't necessarily mean you should never do it. ;) float j; for (j = 0.0; j != 10.0; j += 0.1) { } Keeps the program occupied for a little while. I guess better to time the pause some other way, more accurately and less dependant upon processor speed. You missed the point. Google up "comp.lang.c FAQ" and read Section 14, which is all about floating-point numbers. (In a nutshell: 'j' may never be equal to 10.0, due to rounding errors in the addition operations.) unsigned int m; for (m = 9; m > 0; m -= 2) { } I guess the problem with this one is that m being an unsigned integer will cause problems when you perform 9 - 2 - 2 - 2 - 2 - 2... and never get to be lessthan or equal to 0, so the loop goes on forever. Correct. But note that somebody else already posted abusive but possibly useful code that looked something like this: unsigned m; for (m = 9; m > 0; m -= 2) { if (m > 9) m = 8; foo(m); } I didn't see any FAQ about unsigned arithmetic, but here's something just as good: http://www.eskimo.com/~scs/cclass/int/sx4ca.html HTH, -Arthur Nov 14 '05 #19
 jd*********@yahoo.com (James Dow Allen) wrote: go****@asktoby.com (Toby Newman) wrote: "The for loop is ... very flexible, and novice programmers should take care not to abuse the power it offers." Could someone give an example of this abuse? ... I'd like to see what *not* to do :) http://tinyurl.com/2452h/wnim.htm (scroll about half way down.) If that page is meant to be a troll then ignore this, but why didn't you malloc the whole array in one go? This would have saved screeds of memory and code complexity (although I suppose if you had then you would have been unable to contribute to this thread). Quoting from your page: char Posvalue[13][13][13][13][13][13][13][13][13][13][13][13]; When I try to compile the above statement with FSF's C compiler I get: bonzo.c:1: size of array `Posvalue' is too large typedef char Nodes[13][13][13][13][13][13][13][13][13][13][13][13]; Nodes *Posvalue = calloc(1, sizeof *Posvalue); Nov 14 '05 #20
 >jd*********@yahoo.com (James Dow Allen) wrote: http://tinyurl.com/2452h/wnim.htm (scroll about half way down.) In article <84**************************@posting.google.com > Old Wolf writes:If that page is meant to be a troll then ignore this, but why didn'tyou malloc the whole array in one go? It will will not fit. (It seems to me that he uses a series of sparse arrays, coded rather oddly; but I only glanced at the code.) Quoting from your page: char Posvalue[13][13][13][13][13][13][13][13][13][13][13][13]; When I try to compile the above statement with FSF's C compiler I get: bonzo.c:1: size of array `Posvalue' is too large typedef char Nodes[13][13][13][13][13][13][13][13][13][13][13][13]; Nodes *Posvalue = calloc(1, sizeof *Posvalue); This requires pow(13,12) (23 298 085 122 481) bytes -- requiring about 45 bits' worth of address space (log2(above) is 44.405...). Not a problem on some modern 64-bit architectures, perhaps, but most machines have a bit of trouble handing out over 21 thousand gigabytes (21.7 TB) of virtual memory. :-) -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: forget about it http://web.torek.net/torek/index.html Reading email is like searching for food in the garbage, thanks to spammers. Nov 14 '05 #21
 # Arthur J. O'Dwyer float j; for (j = 0.0; j != 10.0; j += 0.1) { } Keeps the program occupied for a little while. I guess better to time the pause some other way, more accurately and less dependant upon processor speed. You missed the point. Google up "comp.lang.c FAQ" and read Section 14, which is all about floating-point numbers. (In a nutshell: 'j' may never be equal to 10.0, due to rounding errors in the addition operations.) Thanks for the helpful post. I am aware of the existance of float rounding errors, but no so aware that I'm able to spot them in the wild yet :) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) { } -- Toby Nov 14 '05 #22
 Toby Newman wrote: # Arthur J. O'Dwyer> float j;> for (j = 0.0; j != 10.0; j += 0.1) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) Yes. Nov 14 '05 #23
 Toby Newman wrote: # Arthur J. O'Dwyer float j; for (j = 0.0; j != 10.0; j += 0.1) { } Keeps the program occupied for a little while. I guess better to time the pause some other way, more accurately and less dependant upon processor speed. You missed the point. Google up "comp.lang.c FAQ" and read Section 14, which is all about floating-point numbers. (In a nutshell: 'j' may never be equal to 10.0, due to rounding errors in the addition operations.) Thanks for the helpful post. I am aware of the existance of float rounding errors, but no so aware that I'm able to spot them in the wild yet :) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) { } No, by writing: int i; float j; for (i = 0; i < 100; i++) { j = i / 10.0; ... } -- "Churchill and Bush can both be considered wartime leaders, just as Secretariat and Mr Ed were both horses." - James Rhodes. "A man who is right every time is not likely to do very much." - Francis Crick, co-discover of DNA Nov 14 '05 #24
 On Wed, 11 Aug 2004, pete wrote: Toby Newman wrote: # Arthur J. O'Dwyer> float j;> for (j = 0.0; j != 10.0; j += 0.1) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) Yes. No. CBFalconer has it right, in his parallel reply. Toby's loop has the exact same problem as the original: you don't know how many times the loop will be executed! Consider two systems on which this code might be run; on the first, j <-- 0, 0.1, 0.2, 0.3, 0.4, 0.499, 0.599, 0.699, 0.799, 0.899, 0.999 (eleven iterations) On the second, j <-- 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 (ten iterations) Unless you're actually using this loop to distinguish different systems according to such icky floating-point behavior, it's better to stick to comparing integers for equality. HTH, -Arthur Nov 14 '05 #25
 Toby Newman wrote: # Thomas Matthewsfor (i = 0; i < 100; ++i){ --i;} Gets the program stuck in a loop. I guess you could do the same with while(1) {} No. The point is that the index variable is modified within the block of statements. This was _not_ designed as a forever loop. float j;for (j = 0.0; j != 10.0; j += 0.1){} Keeps the program occupied for a little while. I guess better to time the pause some other way, more accurately and less dependant upon processor speed. Nope. The point here is that floating point arithmetic and comparison are not exact enough for this loop. One should not use floating point values for indices in a loop. unsigned int m;for (m = 9; m > 0; m -= 2){} I guess the problem with this one is that m being an unsigned integer will cause problems when you perform 9 - 2 - 2 - 2 - 2 - 2... and never get to be lessthan or equal to 0, so the loop goes on forever. This is another issue on unspecified behavior. The loop causes an underflow at m == 1. One cannot subract the value of "2" from "1" when the domain is restricted to all positive integers (including zero). This is undefined in terms of mathematics. -- Thomas Matthews C++ newsgroup welcome message: http://www.slack.net/~shiva/welcome.txt C++ Faq: http://www.parashift.com/c++-faq-lite C Faq: http://www.eskimo.com/~scs/c-faq/top.html alt.comp.lang.learn.c-c++ faq: http://www.comeaucomputing.com/learn/faq/ Other sites: http://www.josuttis.com -- C++ STL Library book Nov 14 '05 #26
 In article , Thomas Matthews wrote:Toby Newman wrote: # Thomas Matthews unsigned int m;for (m = 9; m > 0; m -= 2){} I guess the problem with this one is that m being an unsigned integer will cause problems when you perform 9 - 2 - 2 - 2 - 2 - 2... and never get to be lessthan or equal to 0, so the loop goes on forever.This is another issue on unspecified behavior.The loop causes an underflow at m == 1. One cannotsubract the value of "2" from "1" when the domainis restricted to all positive integers (includingzero). This is undefined in terms of mathematics. Except that we're talking in terms of C here, not mathematics, and in C this one is well-defined. Unsigned arithmetic wraps -1 around to UINT_MAX, which (if I'm not mistaken) is required to be odd, so you get an infinite loop repeatedly counting down the odd integers in the range of unsigned int. dave -- Dave Vandervies dj******@csclub.uwaterloo.ca OK, then, call it something else. Let's say flog() to remind me what should happen to me when I make silly mistakes like that. --Peter "Shaggy" Haywood in comp.lang.c Nov 14 '05 #27
 Arthur J. O'Dwyer wrote: On Wed, 11 Aug 2004, pete wrote: Toby Newman wrote: # Arthur J. O'Dwyer>> float j;>> for (j = 0.0; j != 10.0; j += 0.1) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) Yes. No. CBFalconer has it right, in his parallel reply. Toby's loop has the exact same problem as the original: you don't know how many times the loop will be executed! No! Your code has the problem. You don't know whether or not j will be less than 10.0 in the body of the loop. link -> data = log(10.0 - j); } link -> next = NULL; Nov 14 '05 #28
 On Thu, 12 Aug 2004, pete wrote: Arthur J. O'Dwyer wrote: On Wed, 11 Aug 2004, pete wrote: Toby Newman wrote: # Arthur J. O'Dwyer>>> float j;>>> for (j = 0.0; j != 10.0; j += 0.1) So, the code would be corrected by instead doing: float j; for (j = 0.0; j < 10.0; j += 0.1) Yes. No. CBFalconer has it right, in his parallel reply. Toby's loop has the exact same problem as the original: you don't know how many times the loop will be executed! No! Your code has the problem. You don't know whether or not j will be less than 10.0 in the body of the loop. link -> data = log(10.0 - j); } link -> next = NULL; I think we've gotten attributions garbled somewhere here. Thomas's intentionally-wrong code was: >>> float j;>>> for (j = 0.0; j != 10.0; j += 0.1) This is wrong, wrong, wrong. Your "corrected" version was: float j; for (j = 0.0; j < 10.0; j += 0.1) This is at least a finite loop, but its behavior is still implementation-defined. CBFalconer in a parallel subthread suggested int jj; for (jj = 0; jj < 100; jj += 1) { double j = jj / 10.0; This is absolutely correct and unimpeachable, and there is absolutely nothing wrong with it. According to me, that is. Notice that /I/ never wrote any code in this thread. I just pointed out that /your/ code was wrong, and /Chuck's/ code was correct. And I stand by that. I think you may have assumed that Thomas's code was really CBFalconer's. Now that you know it's not, are you still argumentative? ;) -Arthur Nov 14 '05 #29
 Chris Torek wrote: Old Wolf writes:If that page is meant to be a troll then ignore this, but why didn'tyou malloc the whole array in one go? typedef char Nodes[13][13][13][13][13][13][13][13][13][13][13][13]; Nodes *Posvalue = calloc(1, sizeof *Posvalue); This requires pow(13,12) (23 298 085 122 481) bytes -- requiring about 45 bits' worth of address space (log2(above) is 44.405...). Not a problem on some modern 64-bit architectures, perhaps, but most machines have a bit of trouble handing out over 21 thousand gigabytes (21.7 TB) of virtual memory. :-) Good point. However I have seen Dan Pop recommend this technique and the OS should optimise sparse arrays by not reserving the space until it is actually used. Speaking of Mr Pop, I haven't seen any posts from him for a while.. what's up? Nov 14 '05 #30
 Old Wolf wrote: Chris Torek wrote:Old Wolf writes:If that page is meant to be a troll then ignore this, but why didn'tyou malloc the whole array in one go? typedef char Nodes[13][13][13][13][13][13][13][13][13][13][13][13]; Nodes *Posvalue = calloc(1, sizeof *Posvalue);This requires pow(13,12) (23 298 085 122 481) bytes -- requiringabout 45 bits' worth of address space (log2(above) is 44.405...).Not a problem on some modern 64-bit architectures, perhaps, butmost machines have a bit of trouble handing out over 21 thousandgigabytes (21.7 TB) of virtual memory. :-) Good point. However I have seen Dan Pop recommend this technique and the OS should optimise sparse arrays by not reserving the space until it is actually used. Speaking of Mr Pop, I haven't seen any posts from him for a while.. what's up? Isn't this the big vacation season in Europe ... where everybody goes to a health spa, to prepare themselves to face the coming Christmas season? -- Ron Collins Air Defense/RTSC/BCS "I have a plan so cunning, you could put a tail on it and call it a weasel" Nov 14 '05 #31
 > >jd*********@yahoo.com (James Dow Allen) wrote: http://tinyurl.com/2452h/wnim.htm Putting this piece of code in context, here's the very first sentence of my lesson9.htm: Programming loses much of its fun when one's programs all look the same. Chris Torek wrote in message news:... ... a series of sparse arrays, coded rather oddly ... Given the above context, I'll take this as a compliment! :-) The 90-line source program in question is *much harder* to read or understand than the average 90-line source program. But that's not a fair comparison. The question should be, how does the net readability of my code compare with another program that *solves the same problem*? I posted the link to this peculiar code almost as a joke, but now it occurs to me that it might pose an interesting challenge for programmers in general, or c.l.c'ers in particular. It would be instructive for me, and perhaps others, to compare with a properly coded version, but we'll need that properly coded version. (It should be a full program that solves Waldo's Nim; otherwise I'm afraid fragments will be posted that simply can't accomplish what the peculiar code does.) Write the program the way it should be; let c.l.c'ers vote on the best solution. I'll be happy to post the winning submission at my website (unless the winner feels this would be a booby prize. :-) It shouldn't take long to do it: as Mr. Torek pointed out, the peculiar part just sets up a sparse array, and the rest is a very simple algorithm which isn't the issue. (A heuristic improvement may exist, but that would be a separate topic for alt.brain.teasers.) A thread based on such a ``contest,'' might be fun for c.l.c, and you should be grateful to me for playing the buffoon whose code needs improvement. But first, let me summarize my feelings about my own code: (1) it was written for play not pay; paid code would have been improved in some ways (though I'm afraid it still would have used a macro like NFOR). (2) nesting 12 loops seems like the natural and best way to write the program; since the loops are essentially identical, using a macro seemed right; with these decisions, packing the calloc() into the for-statement substantially simplified the syntax. You may disapprove, but the intent was to clarify the code, not obfuscate it! (3) some aspects of the code others find ``bad'' are indeed bad. My question is whether the cure would be worse than the disease. We all agree global variables are bad, but we use them when the alternative is dozens of unwieldy function arguments. We all agree long functions are bad, but some of us use them when factorings aren't really helpful. And I'd like to see the "proper" version of this program before agreeing it's better. (4) coding involves trade-offs, and shouldn't be dictated by dogma. (as an extreme example of dogma, one can find old messages in c.l.c with the claim that *longjmp()* is better than *goto* because it's a function, not an (evil) keyword.) (5) as most readers realized, the code indulged a whimsical (or perverse) love of minimalism. I hope some of you also find programming *Fun*! * * * * * * * * * * * * * * * Someone wrote, in effect: Was this a troll? Just do calloc(13*13*13*13*13*13, 13*13*13*13*13*13); [I've rearranged the 13's so the numbers fit size_t.] Errh, my contest offer is sincere, but submissions will be expected to compile and execute on present-day computers. Someone else wrote, in effect: The flaw in this code is the 18 tab characters `indent' needs to add, after `cc -E' ... Was *this* a troll? I personally see nothing wrong with nesting a dozen loops, especially here when the loops are equivalent (just handling different axes of a multi-dimensional structure), but if there *is* something wrong with it, fitting tabs onto paper or screen can't be the problem, can it? And why would anyone think adding 18 indentations to the code is a good idea (unless your 4th grade programming teacher used to hit you with a ruler when you didn't indent every sub-block)? Finally, although we've all used cc -E | indent to decipher obfuscated code, the idea that code like #define NFOR(N) something_very_complicated_but \ whose_complexity_doesn't_involve_N_or_submacros NFOR(1) NFOR(2) NFOR(3) NFOR(4) NFOR(5) NFOR(6) NFOR(7) NFOR(8) NFOR(9) NFOR(10) NFOR(11) NFOR(12) calls for the `cc -E | indent' tool strikes me as inexplicable. James Nov 14 '05 #32
 "Old Wolf" wrote in message news:84**************************@posting.google.c om... Chris Torek wrote: Old Wolf writes: Good point. However I have seen Dan Pop recommend this technique and the OS should optimise sparse arrays by not reserving the space until it is actually used. Speaking of Mr Pop, I haven't seen any posts from him for a while.. what's up? Indeed. I invoked His name in another thread (and was cautioned appropriately) and received nary a word. I did get a slight anal discomforture later in the week, tho. -- Mabden Nov 14 '05 #33

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

 23 posts views Thread by Invalid User | last post: by 9 posts views Thread by Peter Hansen | last post: by 6 posts views Thread by John Pass | last post: by 15 posts views Thread by GS | last post: by 34 posts views Thread by Frederick Gotham | last post: by 6 posts views Thread by Otekpo Emmanuel | last post: by reply views Thread by SwissProgrammer | last post: by reply views Thread by SwissProgrammer | last post: by 1 post views Thread by SwissProgrammer | last post: by 2 posts views Thread by SwissProgrammer | last post: by 1 post views Thread by Divyan | last post: by 10 posts views Thread by SueHopson | last post: by 1 post views Thread by jobsrod | last post: by 1 post views Thread by MitchR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.