Author |
Message |
mer.. #1 / 26
|
 enum - enum ?
What does the current standard say about enum - enum (both same enum type)? I have tried this with 2 compilers; one complained about using enums in an expression (needs cast to int), the other one didn't. I think it would be reasonable for enum - enum to be an integer value, just as ptr - ptr is, and for similar reasons; you want the 'distance' between them. This would also imply enum + int == enum and enum++ is ok Of course, if you do: enum color {red=99, blue=-4, green=200}; then green-red will be 101, not 2, and red++ != blue, but that's your doing. I know (int) green - (int) red will always work, but it's ugly. If enums are too strongly typed (what is this, Pascal?) people will go back to lists of #defines. ----- "Oh carrots! Oh crumbs!" Merlyn Leroy ...rutgers!dayton!rosevax!rose3!starfire!merlyn
|
Tue, 17 Nov 1992 12:31:00 GMT |
|
 |
Doug Gwy #2 / 26
|
 enum - enum ?
Quote:
>What does the current standard say about enum - enum (both same enum type)?
As I recall, enums are now officially ints in disguise.
|
Tue, 17 Nov 1992 02:39:00 GMT |
|
 |
k.. #3 / 26
|
 enum - enum ?
Quote:
>What does the current standard say about enum - enum (both same enum type)?
It says that enums are just ints. Personally, I think I'd be happy to have both enums and chars behave like pointers arithmetically (e.g. char+int == char, enum-enum == int, other combinations illegal), provided there's also a type "byte" ("short short"?) for arithmetic usage. Quote: >I know (int) green - (int) red will always work, but it's ugly. >If enums are too strongly typed (what is this, Pascal?) people will >go back to lists of #defines.
But if enums are too weakly typed, what's their advantage over ints? I tend to use enums only when they would be legal in the strictest compilers, i.e. when the actual values are completely arbitrary. Given the suggested "pointer-like" semantics for arithmetic, and the ability to declare an array indexed by enums (or other types!), I could find more use for them.
int hue[enum color] = { RED: 0x00F, GREEN: 0x0F0, BLUE: 0xF00 }; /* I wish */
|
Tue, 17 Nov 1992 19:29:00 GMT |
|
 |
g.. #4 / 26
|
 enum - enum ?
Quote: > Personally, I think I'd be happy to have both enums and chars behave like > pointers arithmetically (e.g. char+int == char, enum-enum == int, other > combinations illegal), provided there's also a type "byte" ("short short"?) > for arithmetic usage.
I tend to agree (I would prefer "short short" as the adverb here), having learned that Type Systems Are Your Friend and that, in most cases, there is no benefit to be gained from promiscuously flouting the rules of the type system (and significant benefit to be gained by following those rules - just running "lint" on code, including kernels, before building and testing them has often turned up errors). Quote: > But if enums are too weakly typed, what's their advantage over ints?
I hope certain legal but dubious uses of "enum"s will at least generate warnings even from X3J11-conforming compilers; for example, coercing something of type "enum foo" to something of type "enum bar". This might not be as good at catching errors as forbidding those uses, but at least it means that the use wouldn't pass without comment. Quote: > Given the suggested "pointer-like" semantics for arithmetic, and the > ability to declare an array indexed by enums (or other types!), I could > find more use for them. > int hue[enum color] = { RED: 0x00F, GREEN: 0x0F0, BLUE: 0xF00 }; /* I wish */
I agree that it would be nice to support declaring arrays indexed by "enum"s. (What "other types" would be indices? "char", presumably; the only other types I could see would be subrange types - are you proposing adding them to C?) It fits the model of an array as a function from the set of all values of the index type to all values of the base type, although to properly implement that model subrange types would be needed (an array indexed by "int", in this model, would have the set of all values of type "int" as its domain, which implies a VERY big array). One interesting possibility is suggested by the fact that the set of numerical encodings of "enum" values need not be "dense", and thus that enum cookie { chocolate_chip = 1, oreo = 10, oatmeal = 100 }; int price[enum cookie]; might cause "price" to be a sparse array, with lookups in that array done by some technique other than indexing. This is analogous to "switch" statements; the compiler selects different implementations based on the set of values used, with indexing used for a sufficiently "dense" set, various combinations of hashing and table-search used for less-"dense" sets, and a cascade of comparisons used for other sets. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy
|
Tue, 17 Nov 1992 16:38:00 GMT |
|
 |
m.. #5 / 26
|
 enum - enum ?
Quote: >I think it would be reasonable for enum - enum to be an integer value, >just as ptr - ptr is, and for similar reasons; you want the 'distance' >between them. This would also imply enum + int == enum and enum++ is ok
The following statements assume the declaration: enum color {red=1, blue=4, green=5}; enum fruit {apple=1, orange=4, grape=5}; for clarification: color is an enum; red is an enum constant; What is the use of an expression such as red++ ?? Enum constants are integer constants - why would you want to allow the modification of a constant (ie: red++) - might as well use ints. I agree that enums in general should be implemented as a special case of integers - allowed wherever integer constants are allowed, but with extra restrictions regarding assignment of two different enums (color = fruit) and addition of enums or enum constants. Subtracting two enum constants or adding a integer to an enum constant could be useful, but what would you use the addition of two enum constants for? Should enum_constant - enum_constant only be allowed if both enum constants are elements of the same enum type? I would like to have enums and enum constants be flexible, but I also would like the extra type-checking for enums; otherwise I might as well use #define's for compile-time constants. type.
|
Tue, 17 Nov 1992 19:47:00 GMT |
|
 |
Karl Heu #6 / 26
|
 enum - enum ?
Quote:
>[haddock!karl (Karl Heuer) writes:] >>But if enums are too weakly typed, what's their advantage over ints? >I hope certain legal but dubious uses of "enum"s will at least generate >warnings even from X3J11-conforming compilers; for example, coercing >something of type "enum foo" to something of type "enum bar". This >might not be as good at catching errors as forbidding those uses, but >at least it means that the use wouldn't pass without comment.
Perhaps you're right; the May86 dpANS lists under Common Warnings: "A value is given to an object of an enumeration type other than by assignment of an enumeration constant that is a member of that type." (Which seems unusually strict, as it would produce a warning for some perfectly valid code written under the "strong enum" model.) If this or similar wording appears in the final Draft, I expect people will continue to use enum as they do now.
|
Tue, 17 Nov 1992 10:02:00 GMT |
|
 |
Karl Heu #7 / 26
|
 enum - enum ?
Quote:
>[haddock!karl (Karl Heuer) writes:] >>Given the suggested "pointer-like" semantics for arithmetic, and the >>ability to declare an array indexed by enums (or other types!), I could >>find more use for them. >>int hue[enum color] = { RED: 0x00F, GREEN: 0x0F0, BLUE: 0xF00 }; /* I wish */ >I agree that it would be nice to support declaring arrays indexed by >"enum"s. (What "other types" would be indices? "char", presumably; >the only other types I could see would be subrange types - are you >proposing adding them to C?)
Maybe someday -- but no, that wasn't what I was thinking. Some machines can support a[short] with no trouble, but that would raise the question of which types a conforming implementation is *required* to support (and hence can be used in a portable program)... Quote: >One interesting possibility is suggested by the fact that the set of >numerical encodings of "enum" values need not be "dense", and thus that > enum cookie { chocolate_chip = 1, oreo = 10, oatmeal = 100 }; > int price[enum cookie]; >might cause "price" to be a sparse array, with lookups in that array >done by some technique other than indexing. This is analogous to >"switch" statements; the compiler selects different implementations >based on the set of values used, with indexing used for a >sufficiently "dense" set, various combinations of hashing and >table-search used for less-"dense" sets, and a cascade of comparisons >used for other sets.
I glad you posted this -- I was going to mention the same idea myself, but I prefer the feedback so I can tell someone is listening to my ravings. :-) In your example, the implementation might choose to allocate three ints and use a cascade of comparisons (actually, one comparison against "oreo" would suffice). Now, we could assert that a conforming implementation must support *all* types as subscripts, and that "int a[int]" will, if necessary, cause some sort of "smart" lookup. The problem now is that the amount of space required is not known at compile time. If the compiler is going to use a hash table, it can probably make good use of a "hint" from the programmer. (Which probably means another new keyword. Ugh.) Incidentally, I am not suggesting that this feature be incorporated into the new standard -- I realize there's very little hope for that. However, I *do* believe it is a good idea (at least for enum), and would like to see it implemented as an extension. If it catches on, it may be a candidate for the __STDC__==2 release.
|
Tue, 17 Nov 1992 10:18:00 GMT |
|
 |
m.. #8 / 26
|
 enum - enum ?
Quote: > [The current draft standard] says that enums are just ints.
More precisely, their values promote to int, the same way that chars do. Quote: > >If enums are too strongly typed (what is this, Pascal?) people will > >go back to lists of #defines. > But if enums are too weakly typed, what's their advantage over ints?
Perhaps Karl hasn't ever had to maintain a program that uses a "list of #defines" over 90 elements long, with the #define for the length of the list in a different place from the list itself. *I* have. If the original coder hadn't been defensive and made the length #define a bit longer than the actual list then was, things could have gotten verrrrry awkward... Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb #define MSB(type) (~(((unsigned type)-1)>>1))
|
Tue, 17 Nov 1992 15:53:00 GMT |
|
 |
Eddie Wya #9 / 26
|
 enum - enum ?
Quote:
> >I think it would be reasonable for enum - enum to be an integer value, > >just as ptr - ptr is, and for similar reasons; you want the 'distance' > >between them. This would also imply enum + int == enum and enum++ is ok > The following statements assume the declaration: > enum color {red=1, blue=4, green=5}; > enum fruit {apple=1, orange=4, grape=5}; > for clarification: color is an enum; red is an enum constant; > What is the use of an expression such as red++ ??
^^^ I think you mean a variable of type color. color rgb; rgb++ - could be used as the successor function rgb-- - cound be used as the predessor I just tried this with my C complier and it didn't allow an enum variable in the increment statement. I guess they wanted to avoid the semantic issues here. Example rgb = red; rgb++; does rgb == blue or red+1? Quote: > Enum constants are integer constants - why would you want to allow the > modification of a constant (ie: red++) - might as well use ints.
No one should or can modify a constant in C. Again I think you mean a enum variable. Quote: > I agree that enums in general should be implemented as a special case of > integers - allowed wherever integer constants are allowed, but with extra > restrictions regarding assignment of two different enums (color = fruit) > and addition of enums or enum constants. > Subtracting two enum constants or adding a integer to an enum constant could > be useful, but what would you use the addition of two enum constants for?
type enum {offset1 = 3, offset2 = 5, offset3 = 6} offsettype; type enum {index1 = 4, index2 = 9, index3 = 9} index; int where = offset1*sizeof(mytype) + index2; /* array indexing function ^ */ Quote: > Should enum_constant - enum_constant only be allowed if both enum constants > are elements of the same enum type? > I would like to have enums and enum constants be flexible, but I also would > like the extra type-checking for enums; otherwise I might as well use > #define's for compile-time constants. > type.
I view C enumerations a as facility for defining set of interrelated constants. I use them for program readability, not for any extra semantic meaning that is attached. I find typedef enum {PEUTOKEN, PEUFRAME, PEUFFRAME ...} PARSEERRORTYPE; A lot more meaningful than #define PEUTOKEN 0 #define PEUFRAME 1 #define PEUFFRAME 2 ..... -- Eddie Wyatt
|
Tue, 17 Nov 1992 10:53:00 GMT |
|
 |
Karl Heu #10 / 26
|
 enum - enum ?
Quote:
>I just tried [using "++" and "--" for successor and predecessor] with my C >complier and it didn't allow an enum variable in the increment statement. I >guess they wanted to avoid the semantic issues here. Example [given the >declaration: enum color {red=1, blue=4, green=5};] > rgb = red; rgb++; >does rgb == blue or red+1?
Clearly it should be red+1, which should have the value (enum color)2. However, since this value is not a declared member of the set, one could argue that the result is undefined. Quote:
>>I would like to have enums and enum constants be flexible, but I also would >>like the extra type-checking for enums; otherwise I might as well use >>#define's for compile-time constants. >I view C enumerations a as facility for defining set of interrelated >constants. I use them for program readability, not for any extra >semantic meaning that is attached.
Yes, it does add to readability, but I believe in typechecking too. I use "enum" even though "int" will do the same job and more, for the same reason I use "while" instead of "goto": I've observed that programs that can get away with the weaker construct are more likely to be correct. In my programs, using an uncasted enum in an int context is a bug; naturally I prefer the compiler (either cc or lint) to warn me. In fact, while I acknowledge that "typedef creates a new name for a type, not a new type; it does not imply dimensional analysis" (paraphrased from K&R), I'd like to have a feature that *does* produce a new type. (Though I'm not yet sure what operators should be allowed on such a new type.)
|
Tue, 17 Nov 1992 17:55:00 GMT |
|
 |
Alan Mycro #11 / 26
|
 enum - enum ?
Quote: >As I recall, enums are now officially ints in disguise.
Hmm. Checking in the draft (p54 para at line 40) seems to agree with this, but lets consider: enum joke { a=0, b=999999999 }; what happens if 'int' is only 16 bits? Does 'b == 999999999 & 0xffff'? Similarly, consider enum { a = ~0U } on a 32 bit two's complement machine. What is 'a/2'? is it -1/2 (probably 0) or 0x7fffffff? Consider sizeof too: "The implementation many use the set of values ... to allocate ... storage". What does this mean for: enum query { zero=0, one=1 } q; The spec. says zero is int hence sizeof(zero) = sizeof(int). On the other hand sizeof(q) maay be sizeof(char). Is this reasonable? What about sizeof(q)?
|
Tue, 17 Nov 1992 07:46:00 GMT |
|
 |
f.. #12 / 26
|
 enum - enum ?
Quote:
>I can think of only one little quibble with the above: C arrays are >considered to begin with the zero'th element and end at the N-1'th >element, right? So to declare something as > int array[ short ]; >implies that array[] has members indexed by -1, -2, -3, and so on
No. A supscript must simply be some sort of integral type which the copmiler can perform multiplication on or stick into an index register (i.e. it must be something you can add to a pointer). In particuar, pointers may be dereferenced with a negative subscript. According to K&R's C Reference Manual, section 14.3: "By definition, the subscript operator [] is interpreted in such a way that E1 [ E2 ] is identical to * ( (E1) + (E2) )." This means that, since negative numbers can be added to pointers, it is possible to reference negatively indexed members of an array. This would only be useful if you had a pointer to the middle of an array, just as it is only useful to use subscripts less than the size of an array. As an example, consider the code to remove a newline from the end of a string: void trim(string) char *string; { while (*string) ++string; if ( string[-1] == '\n' ) string[-1] = '\0'; } This code is optimized for situations where the newline will not usually be present, otherwise the first string[-1] would be *(--string) and the second would be *string. This is because using a non-zero subscript is usually faster than actually decrementing string, but decrementing it is faster than using the non-zero subscript twice. Note that for simplicity, the example does not properly handle the case where a zero-length string is passed. It would reference the byte immediately before the string in memory, which is undefined in general. Quote: > [...] Say I declare an array > int demo[ 21 : -10 ]; >which I define to mean 'an array of ints, called demo, 21 ints long, >first element is demo[ -10 ]'.
This is not a bad idea, but I would prefer something like the pascal syntax: int demo[ -10 .. 10 ]; Quote: >Now, what is the value of the token 'demo' ?
I think it should be the address of the FIRST element in demo (i.e. demo[-10]). This allows such idiomatic constructs as write(fd, demo, sizeof demo); which would become very non-intuitive if it were necessary to specify the starting or ending indices. Quote: > And further, when I then code up >something like 'frobozz( 2, "hi there", demo );' and frobozz() looks >like > double frobozz( a, b, c ); > int a; > char * b; > int c[]; > { /* and so on... */ >what is the allowable range of indicies of c[] ? -10 .. +10 ? 0 .. >20 ?
The problem here is that the declaration "int c[]" is misleading, it implies that an array is passed to this function, when only a pointer is passed. It makes sence to declare c as "int *", and then you can pass the address of whichever element of demo[] you like, with "demo" alone refering to the add- ress of the FIRST (not necessarily the zero-th) element. I see no real reason to have negative (or even specifiable) ranges of indices for arrays. This is another "educational" feature of pascal that detracts from C's philosophy of being a 'high-level assembly language', i.e., C is meant to provide a portable representation for operations present in most machines' instruction sets. But negative subscripts to POINTERS can be very useful, almost always has a direct mapping to machine instructions, and is already used in a lot of code that I have seen, including most C compilers' C libraries (in things like strcat, strtok, et al.). Michael "Ford" Ditto -=] Ford [=-
-- Michael "Ford" Ditto -=] Ford [=-
|
Tue, 17 Nov 1992 17:58:00 GMT |
|
|
Page 1 of 2
|
[ 26 post ] |
|
Go to page:
[1]
[2] |
|