www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/05/03/11:28:36

Date: Wed, 3 May 1995 8:41:04 -0400 (EDT)
From: Chris Tate <FIXER AT FAXCSL DOT DCRT DOT NIH DOT GOV>
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: Bad bug with for(-;-;-) and an enum name

Offending code:
>
> #include<stdio.h>
> enum{q=1,imax=256};
> main(){double x,y; int i,j,k,l,im=imax;
> printf("A: "); for(i=-im  ;i<im  ;i++) printf("%d ",i); printf("\n");
> printf("B: "); for(i=-imax;i<imax;i++) printf("%d ",i); printf("\n");}
>
>   When this Gnu C++ program runs, loop A prints consecutive numbers on screen
> as expected, but loop B prints <<no numbers at all>>.

You say that this is a C++ program; that's your problem.  C++ and ANSI C
have very different semantics with regard to enums.

This little program is really a C program in disguise; you're using C
I/O libraries, and expecting C's behavior with respect to enumerated
types.  Contrary to popular opinion, I claim that C++ is *not* just a
superset of C; rather, it should be treated as a *different language*.
The similarity between the two is, at this point, an (unfortunate)
historical artifact.  (Yeah, I should put an 'IMHO' in here... :-)

Response:
<
< You are getting punished for grossly misusing (IMHO) the enum facility.
< 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
< -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.

This is a good analysis, but remember that this is only true in C++.

In C, enums are *defined* to be treated as integers.  And, in fact, if
you put the above-quoted code into a file called "test.c" (instead of
"test.cc" and compile it with "gcc -ansi test.c", the resulting binary
runs just as the original poster intended - both the A: and B: loops
print out the desired range of numbers.

C++ treats enums as new, distinct types.  IMHO, this is much more useful
than C's (nearly pointless) equation of enums with ints.

I tested the casting behavior here, and discovered that the necessary
cast is on the *condition*, not the assignment.  Without my ARM I'm not
sure why this should be the case, but writing

	for (i=-imax; i<(int)imax; i++)

works as expected in the B: loop.

----------------------------------------------------------------------
Christopher Tate             | "Ho!  Ha ha!  Guard!  Turn!  Parry!
fixer AT faxcsl DOT dcrt DOT nih DOT gov    |  Dodge!  Spin!  Ha!  Thrust!  <Boing!>"
http://world.std.com/~ctate/ |

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019