Date: Wed, 3 May 1995 19:31:51 +0900 From: Stephen Turnbull To: eliz AT is DOT elta DOT co DOT il Cc: A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk, DJGPP AT SUN DOT SOE DOT CLARKSON DOT EDU Subject: Bad bug with for(-;-;-) and an enum name I knew I shoulda posted last night.... Abusing a guy for cutting his code done to where it exhibits the bug in minimal fashion 'cause you can't see how he'd find code like that useful is not on, hey? Aside to Mr. Appleyard: If you haven't reported it yet, you might want to add some of the info below to your report and send it to 'bug-g++@prep.ai.mit.edu'. Eli quotes A.APPLEYARD > #include > enum{q=1,imax=256}; > main(){double x,y; int i,j,k,l,im=imax; > printf("A: "); for(i=-im ;i printf("B: "); for(i=-imax;i > When this Gnu C++ program runs, loop A prints consecutive numbers > on screen as expected, but loop B prints <>. and then thusly admonishes: You are getting punished for grossly misusing (IMHO) the enum facility. Aaron doesn't say "grossly" but he didn't like it either. More Eli: This facility exists with the sole purpose of declaring variables which can accept only a certain number of discrete values. In your case, you told the compiler *explicitly* that the *only* value it can accept is 256. So don't be mad when the compiler finds it appropriate to implement imax as an unsigned int (or unsigned short), which means that sizeof(imax) == 4 under both DJGPP (g++ 2.6.3) and linux (g++ 2.5.8), and the latter also exhibits the funky loop behavior. I also checked other values and variable names under DJGPP only. For enumerations with all enumerators positive, the incorrect behavior doesn't change. If either imax or q is negative, the program behaves as Appleyard expected. Finally, it behaves "correctly" when compiled as C code under DJGPP gcc 2.6.3. -imax isn't less than imax, and the loop never executes. If you still want to write your program with enums, you should explicitly cast it to int *before* negating. Eli suggested -Wall. GCC does not mention the enumerator, but does harrass me about the 'printf("size = %d\n",sizeof(imax))' statement I added (sizeof is a long int) and complain about the unused variables. At least according to the ARM (1990), G++ is just plain wrong. Heeeeeere's Bjarne: "The 'signed' specifier ... is redundant with [non-char, non-bitfield] integral types [including enums]." (p. 111) "The value of an enumerator must be an 'int' or a value that can be promoted to 'int' by integral promotion." (p. 113) "Appearances to the contrary, there are no operations (except assignment) defined on enumerations; variables and constants of enumeration types are converted to integers before arithmetic [including negation] is done." (p.114) I couldn't find anything in the Info file that directly said anything about the unsigned issue, but there is one option -fenum-int-equiv which is described (under G++ options) as "Permit implicit conversion of `int' to enumeration types. Normally GNU C++ allows conversion of `enum' to `int', but not the other way around." This suggests that GNU intends to follow the ARM on this. Therefore, the ARM interpretation of Appleyard's code is #include enum{q=1,imax=256}; main () { double x,y; int i,j,k,l,im=imax; printf("A: "); for(i=-im ;i http://turnbull.sk.tsukuba.ac.jp/ anon FTP: turnbull.sk.tsukuba.ac.jp Check out Kansai-WWW, too ------------> http://pclsp2.kuicr.kyoto-u.ac.jp/