Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 19, 2004 Bitfields | ||||
---|---|---|---|---|
| ||||
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? |
August 19, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to nail | 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?
>
>
|
August 19, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Minkov | 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: >> 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? >> >> 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. |
August 19, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to nail | 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... >> >> 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? >>> >>> > > 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. 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/ |
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | In article <opsczz26cv5a2sq9@digitalmars.com>, Regan Heath says... > >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... >>> >>> 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? >>>> >>>> >> >> 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. > >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/ 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(); } |
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to nail | 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/ |
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath |
>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
}
|
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to nail | 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 used 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. You /could/ suggest that Walter do something like: # bitfield enum Color { RED, GREEN, BLUE }; // no initializer values needed 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: # enum Color { RED, GREEN, BLUE }; // no initializer values needed then you can just declare your "bitfield variables" like this: # bit[Color.max+1] xxx; and subsequently refer to: # (xxx[Color.RED] || xxx[Color.BLUE]) Will that not do? Jill |
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arcane Jill | >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: > ># bitfield enum Color { RED, GREEN, BLUE }; // no initializer values needed > >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: > ># enum Color { RED, GREEN, BLUE }; // no initializer values needed > >then you can just declare your "bitfield variables" like this: > ># bit[Color.max+1] xxx; > >and subsequently refer to: > ># (xxx[Color.RED] || xxx[Color.BLUE]) > >Will that not do? This is not type safe and bulky > >Jill > > |
August 20, 2004 Re: Bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to nail | 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. >># (xxx[Color.RED] || xxx[Color.BLUE]) >> >>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 |
Copyright © 1999-2021 by the D Language Foundation