Hey Chip,
Sorry about that. If you look at the output of dtrace -Se, you can get a feel
for the problem:
DIFO 0x6e3980 returns D type (integer) (size 1)
OFF OPCODE INSTRUCTION
00: 29050001 ldgs DT_VAR(1280), %r1 ! DT_VAR(1280) = "u1"
01: 1f010001 ldub [%r1], %r1
02: 25000002 setx DT_INTEGER[0], %r2 ! 0x0
03: 05010201 srl %r1, %r2, %r1
04: 25000102 setx DT_INTEGER[1], %r2 ! 0x1
05: 03010201 and %r1, %r2, %r1
06: 23000001 ret %r1
NAME ID KND SCP FLAG TYPE
u1 500 scl glb r D type (union) by ref (size 2)
DIFO 0x6e3a00 returns D type (integer) (size 1)
OFF OPCODE INSTRUCTION
00: 29050001 ldgs DT_VAR(1280), %r1 ! DT_VAR(1280) = "u1"
01: 25000002 setx DT_INTEGER[0], %r2 ! 0x1
02: 07010201 add %r1, %r2, %r1
03: 1f010001 ldub [%r1], %r1
04: 25000102 setx DT_INTEGER[1], %r2 ! 0x0
05: 05010201 srl %r1, %r2, %r1
06: 25000202 setx DT_INTEGER[2], %r2 ! 0x7f
07: 03010201 and %r1, %r2, %r1
08: 23000001 ret %r1
This DIF corresponds to the u1.s1.b1 and u1.s1.b2 in your first printf()
action. Note that the amount we''re shifting both is the same -- clearly
a
bug.
I''ve filed this bug for you:
6465277 bitfield handling could use some work
Adam
On Sat, Aug 19, 2006 at 10:46:19AM -0500, Chip Bennett
wrote:> I''m having some trouble using union. The results are not what I
would
> expect. I tried the same program in C and got the results I would
> expect. Here is the D program:
>
> #pragma D option quiet
> union u1tag
> {
> unsigned char c;
> struct
> {
> unsigned int b1:1;
> unsigned int b2:7;
> } s1;
> } u1;
> BEGIN
> {
> u1.c = 255;
> printf ("%d %d %d\n", u1.c, u1.s1.b1, u1.s1.b2);
> u1.c = 0;
> u1.s1.b1 = 1;
> u1.s1.b2 = 127;
> printf ("%d %d %d\n", u1.c, u1.s1.b1, u1.s1.b2);
> exit(0);
> }
>
> and here is the C program:
>
> union u1tag
> {
> unsigned char c;
> struct
> {
> unsigned int b1:1;
> unsigned int b2:7;
> } s1;
> } u1;
> main()
> {
> u1.c = 255;
> printf ("%d %d %d\n", u1.c, u1.s1.b1, u1.s1.b2);
> u1.c = 0;
> u1.s1.b1 = 1;
> u1.s1.b2 = 127;
> printf ("%d %d %d\n", u1.c, u1.s1.b1, u1.s1.b2);
> exit(0);
> }
>
> The D program yields:
> 255 1 0
> 128 1 127
> and the C program yields:
> 255 1 127
> 255 1 127
>
> It appears, in the D program, the bit fields are aligning on a byte
> boundary rather than in the same byte as they do in the C program. Am I
> correct in expecting these results to be the same? Have I run into a bug?
>
> Thanks,
> Chip
> _______________________________________________
> dtrace-discuss mailing list
> dtrace-discuss at opensolaris.org
--
Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl