digitalmars.D - Bitfields
- nail (12/12) Aug 18 2004 What about integrated bitfields in D?
- Ilya Minkov (2/20) Aug 19 2004
- nail (9/29) Aug 19 2004 No! In this way I can use CA as index, for example. Or if you mean assoc...
- Regan Heath (24/57) Aug 19 2004 How about this...
- nail (23/83) Aug 20 2004 Gi-gi-gi. Following code compiles and runs normaly, while I expected
-
Regan Heath
(23/45)
Aug 20 2004
On Fri, 20 Aug 2004 07:16:22 +0000 (UTC), nail
- nail (31/42) Aug 20 2004 I'm not sure, that this behaviour of compiler is the best case. First: h...
- Arcane Jill (17/25) Aug 20 2004 Ignoring for now the whole enums being annoyingly verbose thing, already
- nail (7/23) Aug 20 2004 It can be not power of two. Either 0 or 3 for example. Remember window's
- Arcane Jill (12/18) Aug 20 2004 Good point. That's more like the old struct { int x : n }; objects you g...
-
Carlos Santander B.
(39/39)
Aug 20 2004
"Arcane Jill"
escribió en el mensaje - nail (2/8) Aug 21 2004
- Regan Heath (26/80) Aug 20 2004 There are degrees of "strong" in D's case, it's not that strongly typed.
- Mark T (3/4) Aug 21 2004 I guess you could use C functions underneath to do the bitfield stuff. O...
What about integrated bitfields in D? It would be nice if I write: enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void foo(bitfield A a) { .. } Then I can use combination of values in A as parameter and can't mix it with values in B or constant C. Is it necessary for D?
Aug 18 2004
I think if we had a nice way to assemble bitarrays, it would do that. nail schrieb:What about integrated bitfields in D? It would be nice if I write: enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void foo(bitfield A a) { .. } Then I can use combination of values in A as parameter and can't mix it with values in B or constant C. Is it necessary for D?
Aug 19 2004
In article <cg1ums$1o4e$1 digitaldaemon.com>, Ilya Minkov says...I think if we had a nice way to assemble bitarrays, it would do that. nail schrieb:No! In this way I can use CA as index, for example. Or if you mean associative array I can't use literals and construction becomes bulky. bit[A] param; param[AA] = true; param[AC] = true; foo(param); very long... Correct me if I understood smthing incorrectly.What about integrated bitfields in D? It would be nice if I write: enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void foo(bitfield A a) { .. } Then I can use combination of values in A as parameter and can't mix it with values in B or constant C. Is it necessary for D?
Aug 19 2004
On Thu, 19 Aug 2004 18:03:10 +0000 (UTC), nail <nail_member pathlink.com> wrote:In article <cg1ums$1o4e$1 digitaldaemon.com>, Ilya Minkov says...How about this... import std.stdio; enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void bar(A a) { bit[] arr; arr = (cast(bit *)&a)[0..8]; foreach(bit b; arr) printf("%d\n",cast(int)b); printf("\n"); } void main() { bar(A.AA|A.AB); bar(A.AB|A.AC); } Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/I think if we had a nice way to assemble bitarrays, it would do that. nail schrieb:No! In this way I can use CA as index, for example. Or if you mean associative array I can't use literals and construction becomes bulky. bit[A] param; param[AA] = true; param[AC] = true; foo(param); very long... Correct me if I understood smthing incorrectly.What about integrated bitfields in D? It would be nice if I write: enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void foo(bitfield A a) { .. } Then I can use combination of values in A as parameter and can't mix it with values in B or constant C. Is it necessary for D?
Aug 19 2004
In article <opsczz26cv5a2sq9 digitalmars.com>, Regan Heath says...On Thu, 19 Aug 2004 18:03:10 +0000 (UTC), nail <nail_member pathlink.com> wrote:Gi-gi-gi. Following code compiles and runs normaly, while I expected compile-time error: import std.c.stdio; enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void bar(A a) { bit[] arr; arr = (cast(bit *)&a)[0..8]; foreach(bit b; arr) printf("%d\n",cast(int)b); printf("\n"); if (a & B.BB) // Hm. Is this normal? printf("Yo!\n"); } void main() { bar(A.AA|B.BB); // Why B.BB is compiled??? bar(A.AB|A.AC); getch(); }In article <cg1ums$1o4e$1 digitaldaemon.com>, Ilya Minkov says...How about this... import std.stdio; enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void bar(A a) { bit[] arr; arr = (cast(bit *)&a)[0..8]; foreach(bit b; arr) printf("%d\n",cast(int)b); printf("\n"); } void main() { bar(A.AA|A.AB); bar(A.AB|A.AC); } Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/I think if we had a nice way to assemble bitarrays, it would do that. nail schrieb:No! In this way I can use CA as index, for example. Or if you mean associative array I can't use literals and construction becomes bulky. bit[A] param; param[AA] = true; param[AC] = true; foo(param); very long... Correct me if I understood smthing incorrectly.What about integrated bitfields in D? It would be nice if I write: enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void foo(bitfield A a) { .. } Then I can use combination of values in A as parameter and can't mix it with values in B or constant C. Is it necessary for D?
Aug 20 2004
On Fri, 20 Aug 2004 07:16:22 +0000 (UTC), nail <nail_member pathlink.com> wrote: <snip>Gi-gi-gi. Following code compiles and runs normaly, while I expected compile-time error:Yeah.. I am not 100% certain, but, from my tests, which are: bar(1); //cannot implicitly convert expression 1 of type int to A bar(1|A.AA); //cannot implicitly convert expression 1 | cast(A)1 of type int to A bar(B.BB|A.AA); //cannot implicitly convert expression cast(B)4 | cast(A)1 of type B to A bar(A.AA|1); //ok bar(A.AA|B.BB); //ok it appears | causes each operand to be converted to 'int' then the result is converted back to the first operands type. So the following: bar(A.AA|<anything that can implicitly be converted to int>); will work. Walter can tell us for sure.import std.c.stdio; enum A {AA = 0x1, AB = 0x2, AC = 0x4} enum B {BA = 0x8, BB = 0x4, BC = 0x0} const uint CA = 0x80; void bar(A a) { bit[] arr; arr = (cast(bit *)&a)[0..8]; foreach(bit b; arr) printf("%d\n",cast(int)b); printf("\n"); if (a & B.BB) // Hm. Is this normal?I believe so, & probably does the same as | i.e. it tries to implicitly convert each operand to 'int', and the result back to the type of the first operand, in this case an A.printf("Yo!\n"); } void main() { bar(A.AA|B.BB); // Why B.BB is compiled???See my reasoning/assumption/conclusion above.bar(A.AB|A.AC); getch(); }Regards, Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 20 2004
bar(1); //cannot implicitly convert expression 1 of type int to A bar(1|A.AA); //cannot implicitly convert expression 1 | cast(A)1 of type int to A bar(B.BB|A.AA); //cannot implicitly convert expression cast(B)4 | cast(A)1 of type B to A bar(A.AA|1); //ok bar(A.AA|B.BB); //ok it appears | causes each operand to be converted to 'int' then the result is converted back to the first operands type. So the following: bar(A.AA|<anything that can implicitly be converted to int>); will work. Walter can tell us for sure.I'm not sure, that this behaviour of compiler is the best case. First: how can I in a language with strong types use combination of different types?! No mater that implicitly they are integers. I even can't understand how I can use combination of constants of one type while function accepts value of enumerated, enum(!), enumeration(!), case value(!), one value(!) in other words. Predecoration looks little ugly. I prefer use <enum value> instead of <enum type> enum value. IMHO the best case for D if the following code will compile as expected in comments: enum Color { RED = 1, GREEN = 2, ORANGE = 4, } enum Fruit { ORANGE = 1, APPLE = 8, } void xxx(Color color) {...} void yyy(bitfield Color colors) {...} void zzz(Fruit f) {...} void main() { xxx(RED); // ok. xxx(RED | GREEN); // error: bitfield not accepted xxx(ORANGE); // ok. Value 4 (not 1) used yyy(RED | ORANGE); // ok. Value 4 for ORANGE used yyy(RED | APPLE); // error: APPLE not fount in Color enum zzz(ORANGE); // ok. Value 1 (not 4) used }
Aug 20 2004
In article <cg4tdf$ado$1 digitaldaemon.com>, nail says...enum Color { RED = 1, GREEN = 2, ORANGE = 4, }void yyy(bitfield Color colors) {...}yyy(RED | ORANGE); // ok. Value 4 for ORANGE usedIgnoring for now the whole enums being annoyingly verbose thing, already explored in another thread a few days ago, I have to say I don't like your bitfield idea, the main reason being that there is no compile-time check that the enum values are powers of two. You /could/ suggest that Walter do something like: to ask the compiler to choose the constants for you - that would be better. But before you start exploring that idea, consider that we already have bit[] arrays (aka bool[] arrays). So you can already do: then you can just declare your "bitfield variables" like this: and subsequently refer to: Will that not do? Jill
Aug 20 2004
Ignoring for now the whole enums being annoyingly verbose thing, already explored in another thread a few days ago, I have to say I don't like your bitfield idea, the main reason being that there is no compile-time check that the enum values are powers of two.It can be not power of two. Either 0 or 3 for example. Remember window's function MessageBox. Last parameter is bitfield that indicates what set of buttons and what icon to use. MB_OK is equal to 0, so I can write MB_ICONWARNING | MB_OK for readability only. Or remember window styles, imagine WS_POPUP = 0x1 and WS_CAPTION = 0x2, then I want to have const WS_OVERLAPED_WINDOW = WS_POPUP | WS_CAPTION == 3.You /could/ suggest that Walter do something like: to ask the compiler to choose the constants for you - that would be better. But before you start exploring that idea, consider that we already have bit[] arrays (aka bool[] arrays). So you can already do: then you can just declare your "bitfield variables" like this: and subsequently refer to: Will that not do?This is not type safe and bulkyJill
Aug 20 2004
In article <cg54eu$e1t$1 digitaldaemon.com>, nail says...It can be not power of two.Good point. That's more like the old struct { int x : n }; objects you got in C. But in the D overview, Walter lists among the things to drop: "Bit fields of arbitrary size. Bit fields are a complex, inefficient feature rarely used." So that takes us back to ANDing and ORing constants together, which is back where we started.You'll get no argument from me there! But then, D is not a typesafe language. If it were, then bool, int, char and enum would not be mutually implicitly convertible.Will that not do?This is not type safeand bulkyI've never been particularly bothered by that. Still, I'm quite happy to accept syntactic sugar so long as things stay readable. Arcane Jill
Aug 20 2004
"Arcane Jill" <Arcane_member pathlink.com> escribió en el mensaje news:cg5jte$m33$1 digitaldaemon.com | In article <cg54eu$e1t$1 digitaldaemon.com>, nail says... | || It can be not power of two. | | Good point. That's more like the old struct { int x : n }; objects you got in C. | But in the D overview, Walter lists among the things to drop: "Bit fields of | arbitrary size. Bit fields are a complex, inefficient feature rarely used." So | that takes us back to ANDing and ORing constants together, which is back where | we started. | | ||| ||| Will that not do? || || This is not type safe | | You'll get no argument from me there! But then, D is not a typesafe language. If | it were, then bool, int, char and enum would not be mutually implicitly | convertible. | | || and bulky | | I've never been particularly bothered by that. Still, I'm quite happy to accept | syntactic sugar so long as things stay readable. | | Arcane Jill IMHO, the way Delphi deals with it is better: they're not enums, they're sets. So you don't check if a certaing bit is set, but if a certain element is present. They /could/ be implemented as bitfields, but for the user they look like sets. IMHO ----------------------- Carlos Santander Bernal
Aug 20 2004
In article <cg6dun$145f$1 digitaldaemon.com>, Carlos Santander B. says...IMHO, the way Delphi deals with it is better: they're not enums, they're sets. So you don't check if a certaing bit is set, but if a certain element is present. They /could/ be implemented as bitfields, but for the user they look like sets. IMHOYop. Maybe this is most elegant and perfect way----------------------- Carlos Santander Bernal
Aug 21 2004
On Fri, 20 Aug 2004 13:13:20 +0000 (UTC), nail <nail_member pathlink.com> wrote:There are degrees of "strong" in D's case, it's not that strongly typed.bar(1); //cannot implicitly convert expression 1 of type int to A bar(1|A.AA); //cannot implicitly convert expression 1 | cast(A)1 of type int to A bar(B.BB|A.AA); //cannot implicitly convert expression cast(B)4 | cast(A)1 of type B to A bar(A.AA|1); //ok bar(A.AA|B.BB); //ok it appears | causes each operand to be converted to 'int' then the result is converted back to the first operands type. So the following: bar(A.AA|<anything that can implicitly be converted to int>); will work. Walter can tell us for sure.I'm not sure, that this behaviour of compiler is the best case. First: how can I in a language with strong types use combination of different types?!No mater that implicitly they are integers. I even can't understand how I can use combination of constants of one type while function accepts value of enumerated, enum(!), enumeration(!), case value(!), one value(!) in other words.Enum's can take a base type eg. enum A : ubyte {A} But Enums *must* be integral types you cannot say: enum A : double {A} As they are all integral types you can implicitly convert them. It does still check things like.. enum A : ubyte {A} enum B : {A} void foo(A a){} void main() { foo(A.A|B.A); } test4.d(8): function foo (A a) does not match argument types (int) test4.d(8): cannot implicitly convert expression cast(int)(0) | cast(B)0 of type int to APredecoration looks little ugly. I prefer use <enum value> instead of <enum type> enum value. IMHO the best case for D if the following code will compile as expected in comments: enum Color { RED = 1, GREEN = 2, ORANGE = 4, } enum Fruit { ORANGE = 1, APPLE = 8, } void xxx(Color color) {...} void yyy(bitfield Color colors) {...} void zzz(Fruit f) {...} void main() { xxx(RED); // ok. xxx(RED | GREEN); // error: bitfield not accepted xxx(ORANGE); // ok. Value 4 (not 1) used yyy(RED | ORANGE); // ok. Value 4 for ORANGE used yyy(RED | APPLE); // error: APPLE not fount in Color enum zzz(ORANGE); // ok. Value 1 (not 4) used }See my other thread entitled 'Enums are annoyingly verbose'. I think some times the 'decoration' is superfluous, there are several occasions when it is not however. (the other thread has some examples) Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 20 2004
In article <cg1id4$lou$1 digitaldaemon.com>, nail says...What about integrated bitfields in D?I guess you could use C functions underneath to do the bitfield stuff. Of course that adds overhead.
Aug 21 2004