IIRC, enums are always ints, but the signedness is implementation defined. In the common case (gcc on x86 and Linux at least), you get unsigned unless you explicitly assign a negative value to one of the constants. That's why you tend to get warnings when x is some enum variable and you try to check for x < 0 before using it as an array index. But of course, the check isn't really redundant, unless you know you'll always build with exactly the same compiler. But I'm digressing...alexfru wrote:OTOH, enums by default fit into signed ints and if an enumeration constant doesn't fit into a signed int you should get a compilation error.
Does my keyboard.h work?
Re: Does my keyboard.h work?
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: Does my keyboard.h work?
Yes, but as I said earlier, if you are using an enumeration to define constants without regard to order, you're Doing It Wrong. The purpose of enum is to define an ordering; that it does so by defining constants is a side effect, not the purpose of the construct. Some languages which support enumerations (e.g., Ada) don't allow you to directly access the underlying constant values for this very reason (they usually provide an accessor function such as ord() if you absolutely must have the enumeration of a specific enumeration constant).
Oh, and C has a const keyword too, now, and has for decades. It may not work quite as you would expect, but it is there, and unlike #define, it does specify type.
Oh, and C has a const keyword too, now, and has for decades. It may not work quite as you would expect, but it is there, and unlike #define, it does specify type.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Re: Does my keyboard.h work?
I never heard that enums define something that must be ordered. To me it seems pretty logical to use them for related things. Isn't it a common practice to use them for completely unordered error codes?
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
- Alan Kay
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: Does my keyboard.h work?
Common? Yes. Sensible? Not hardly.
Well, not to me, anyway. YMMV.
It is sort of like arguing that using fflush() to flush* input streams (which shouldn't even work, though many badly broken implementations allow it) is the right thing to do because it is a common approach. The fact that fflush() should only be used for, should only work for, output streams is still an important point, because that is what it was intended for and really only makes sense for.
Breaking the model out of pragmatism is one thing, breaking it out of laziness or convenience is another.
It does seem that people have forgotten that this was the original idea**, though, and a lot of (kinda-sorta) working code uses it, so maybe I'm the crazy one here. After all, we all know I am mad anyway, so this would be just one more thing I am insane regarding.
1) Before Unix ruled the world, flushing a buffer meant dumping its contents, not forcing it to go to completion. Who decided that calling the 'force output to completion' function fflush() was a good idea? (Dennis Ritchie, apparently, which is one more thing for which he deserves the blame.)
2) the enum keyword was a relatively late addition, being introduced in the ANSI standard in 1989. It was something of an afterthought, meant to appease the Ada and Pascal fans who were being force to use C as it became an all-consuming juggernaut, but the intention was thought to be clear from the name. Apparently not.
Well, not to me, anyway. YMMV.
It is sort of like arguing that using fflush() to flush* input streams (which shouldn't even work, though many badly broken implementations allow it) is the right thing to do because it is a common approach. The fact that fflush() should only be used for, should only work for, output streams is still an important point, because that is what it was intended for and really only makes sense for.
Breaking the model out of pragmatism is one thing, breaking it out of laziness or convenience is another.
It does seem that people have forgotten that this was the original idea**, though, and a lot of (kinda-sorta) working code uses it, so maybe I'm the crazy one here. After all, we all know I am mad anyway, so this would be just one more thing I am insane regarding.
1) Before Unix ruled the world, flushing a buffer meant dumping its contents, not forcing it to go to completion. Who decided that calling the 'force output to completion' function fflush() was a good idea? (Dennis Ritchie, apparently, which is one more thing for which he deserves the blame.)
2) the enum keyword was a relatively late addition, being introduced in the ANSI standard in 1989. It was something of an afterthought, meant to appease the Ada and Pascal fans who were being force to use C as it became an all-consuming juggernaut, but the intention was thought to be clear from the name. Apparently not.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
- MichaelFarthing
- Member
- Posts: 167
- Joined: Thu Mar 10, 2016 7:35 am
- Location: Lancaster, England, Disunited Kingdom
Re: Does my keyboard.h work?
I can't speak for ADA but in Pascal the idea was far more concerned with the internal semantics of the programme being visible in the code. Thus, you would have types such as:Schol-R-LEA wrote: the enum keyword was a relatively late addition, being introduced in the ANSI standard in 1989. It was something of an afterthought, meant to appease the Ada and Pascal fans who were being force to use C as it became an all-consuming juggernaut, but the intention was thought to be clear from the name. Apparently not.[/i]
Suit=(Clubs, Diamonds, Hearts, Spades)
Season=(Spring, Summer, Autumn, Winter)
House=(Coopers, Maples, Mellers, Whites)
FileSystem=(EXT2, EXT3, EXT4, FAT12, FAT16, FAT32, NTFS)
The first two do have some sort of ordering idea, but the last two don't apart from being in a conventional alphabetic order
The motivation, however, is
(a) to make the code reflect what is being done (the ultimate ideal would be for the code to be self-documenting):
if (DriveFileSystem==FAT12) {
print("Time to upgrade your system, mate")
}
(b) to make it difficult to assign values that are meaningless to the program:
DriveFileSystem=5
Error: Cannot assign integer to variable of type 'FileSystem'
or
DriveFileSystem=Hearts
Error: Hearts is not a FileSystem.
That's not to say that the ordering was not both used and useful, but I think it is wrong to regard it as a prime reason for the construct.
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: Does my keyboard.h work?
Fair enough. As I said, however, enumerations are a special case of that kind of discrete-valued type, and the lack of discrete-valued types of a more general sort in C, and the fact that the language exposes the underlying implementation, are why we tend to see enumerations as defining valued constants rather than an ordering or a set of discrete data points.
Still, at this point I will concede that I have been making too much of the issue of ordering. I have been a bit caught up in the idea of enumerations being for enumerating, and I'll admit that using them for defining constants isn't actually a bad thing in and of itself. I still would say that their primary purpose is to define a set of discrete identities, and I don't dispute that using them for defining constants is useful, but... well, I can't help but feel that this is as much a matter of the lack of richness in the language than it is of programmers misusing something.
Probably it's because I've gotten used to the idea that a language can define new forms of data construct- not just new types or classes, but new kinds of types and ways of defining them - something which is a pretty basic thing in Lisps. Once you have lexical macros (especially read macros) and a self-consistent base syntax, the difference between 'core language' and 'library' pretty much disappears from the perspective of the client-programmer. I certainly intend to to have a lot of different kinds of domains in the standard library for Thelema (if I ever get around to developing it), including things like different kinds of enumerations, sets, ranged types, ordered and unordered collections, and so forth, some of which will have their own literal syntax defined for them. The core language will be tiny - smaller even than Scheme, but with a lot more focus on the programming tools such as package management, scoping rules, generic programming, compiler-level extensibility, dynamic selection of automatic memory management models, and controlling the interface with the system - but I hope to eventually build a large suite of libraries to go with it.
Still, at this point I will concede that I have been making too much of the issue of ordering. I have been a bit caught up in the idea of enumerations being for enumerating, and I'll admit that using them for defining constants isn't actually a bad thing in and of itself. I still would say that their primary purpose is to define a set of discrete identities, and I don't dispute that using them for defining constants is useful, but... well, I can't help but feel that this is as much a matter of the lack of richness in the language than it is of programmers misusing something.
Probably it's because I've gotten used to the idea that a language can define new forms of data construct- not just new types or classes, but new kinds of types and ways of defining them - something which is a pretty basic thing in Lisps. Once you have lexical macros (especially read macros) and a self-consistent base syntax, the difference between 'core language' and 'library' pretty much disappears from the perspective of the client-programmer. I certainly intend to to have a lot of different kinds of domains in the standard library for Thelema (if I ever get around to developing it), including things like different kinds of enumerations, sets, ranged types, ordered and unordered collections, and so forth, some of which will have their own literal syntax defined for them. The core language will be tiny - smaller even than Scheme, but with a lot more focus on the programming tools such as package management, scoping rules, generic programming, compiler-level extensibility, dynamic selection of automatic memory management models, and controlling the interface with the system - but I hope to eventually build a large suite of libraries to go with it.
Last edited by Schol-R-LEA on Sat Nov 19, 2016 12:09 pm, edited 1 time in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Re: Does my keyboard.h work?
C99 says in 6.7.2.2 Enumeration specifiers:Kevin wrote:IIRC, enums are always ints, but the signedness is implementation defined.
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
So, no unsigned int. Can probably be unsigned char/short if converts into signed int (I'd need to check for this), but even so, in all expressions, except sizeof, it would behave as a signed int because of the default conversions applied to operator operands.
Re: Does my keyboard.h work?
Paragraph 2 is only about the allowed values for the enum constants, it doesn't say anything about whether a variable of the enum type is signed or unsigned. For the latter question, paragraph 4 is relevant: "Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration." So unless you have negative enum constants, an enum variable can be treated as unsigned, and I'm pretty sure that gcc does this.
Re: Does my keyboard.h work?
You're right.Kevin wrote:Paragraph 2 is only about the allowed values for the enum constants, it doesn't say anything about whether a variable of the enum type is signed or unsigned. For the latter question, paragraph 4 is relevant: "Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration." So unless you have negative enum constants, an enum variable can be treated as unsigned, and I'm pretty sure that gcc does this.