Jump to page: 1 2
Thread overview
Bitfields
Aug 19, 2004
nail
Aug 19, 2004
Ilya Minkov
Aug 19, 2004
nail
Aug 19, 2004
Regan Heath
Aug 20, 2004
nail
Aug 20, 2004
Regan Heath
Aug 20, 2004
nail
Aug 20, 2004
Arcane Jill
Aug 20, 2004
nail
Aug 20, 2004
Arcane Jill
Aug 21, 2004
nail
Aug 21, 2004
Regan Heath
Aug 21, 2004
Mark T
August 19, 2004
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
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
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
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
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
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
>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
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
>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
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


« First   ‹ Prev
1 2