Hi, I get a curious result when compiling such a following code :
typedef union { unsigned char cCtrlFullByte; struct { unsigned char bEnable : 1; unsigned char cUnused : 7; } cCtrlStruct; } CtrlUnion; void main (void) { unsigned char dummy = 0x55; CtrlUnion xdata bitUnion; bitUnion.cCtrlStruct.bEnable = dummy & 0x40; return; }
MOV A,#0x55 ANL A,#0x00 MOV R7,A MOV DPTR, #0x0000 MOVX A,@DPTR ANL A,#0xFE ORL A,R7 MOVX @DPTR, A
In the standard it is stated that a bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits. In your case it's unsigned integer 1 bit wide. Conversion rules for unsigned integers imply that the compiler should take the LSB, which it did. Regards, Mike
Why not, but how do you explain a different casting rule when the destination is a "real bit"
void main (void) { unsigned char dummy = 0x55; bit bitValue; bitValue = dummy & 0x40; return; }
MOV A,#0x55 MOV C, 0xE0.6 MOV 0x20.0, C
MOV A,#0x55 ANL A,#0x44 ADD A,#0xFF MOV 0x20.0, C
The bit type is a specific Keil extension, so they can implement it in the most efficient, target-specific way they can think of - without having to worry about any other ANSI constraints; Bitfields, on the other hand, are standard ANSI - so Keil may well be constrained in their implementation (and implementations of bitfields are notorious for being inefficient!) BTW: Have you disabled the defualt ANSI Integer Promotions?
> The bit type is a specific Keil extension, > so they can implement it in the most efficient, > target-specific way they can think of - without > having to worry about any other ANSI constraints; Why not, but it is not a reason to have opposite result when using a bit type or a bit in bit-field type !!! > Bitfields, on the other hand, are standard ANSI > - so Keil may well be constrained in their > implementation (and implementations of bitfields > are notorious for being inefficient!) My problem is not efficiency but COHERENCY of the compiled code ! If I used a bit-field type stored in BDATA, or a byte with sbit declarations, the result will be different !!! So, if you write your code using Keil bit type, the result will be good, whereas using bit-field type (for portability), the result will be false !!! Not really coherent ! ;-( Is that a compiler bug or a normal issue ? > BTW: Have you disabled the defualt ANSI Integer Promotions? Obviously Yes, but no change. Arnaud DELEULE
The code in Araund's example is correct. The first example where C is set from E0.6 (actually Accumulator bit 6 .. E0 is the ACC sfr) is exactly the value specified. In the second example, the and with 0x44 and add 0xff sets carry if either of the two bits in the mask are non-zero. Looks to me like the compiler did exactly as it should.
You're right. It does exactly what it should when the destination is a Keil "bit" type. If the type of the destination is a 1-bit wide field in a bit-field structure, the result will be different. For me, that should not happen. Regards Arnaud