Does anybody knows, Keil C compiler V7.xx supports bit fields with signed types or not? The code always generated same as for unsigned types. This is compiler bug or feature? My code compiled with Keil C fails on MCU, but works excellent on PC when compiled with gcc. Example: struct xxx { signed y: 7; }; struct xxx *s; volatile int i; i = s->y; /* This operator does not extends y to i with sign, instead all higher bits masked with zeros */ ; i = s->y; MOV DPTR,#s?25158 MOVX A,@DPTR MOV R3,A INC DPTR MOVX A,@DPTR MOV R2,A INC DPTR MOVX A,@DPTR MOV R1,A LCALL ?C?ILDPTR MOV R5,A MOV R4,B ANL A,#07FH MOV R7,A MOV DPTR,#i?25159 CLR A MOVX @DPTR,A INC DPTR MOV A,R7 MOVX @DPTR,A i=-2, s->y=i; /* This operator again only masking higher bits of i without carying of sign bit */ ; i=-2; MOV DPTR,#i?25159 MOV A,#0FFH MOVX @DPTR,A INC DPTR DEC A MOVX @DPTR,A ; s->y=i; MOV DPTR,#i?25159+01H MOVX A,@DPTR ANL A,#07FH MOV R7,A MOV A,R5 ANL A,#080H MOV R5,A MOV A,R4 MOV R6,A MOV A,R5 ORL A,R7 MOV R7,A MOV A,R6 MOV B,R7 LCALL ?C?ISTPTR
Per the ANSI standard, bit fields are always of type "int". Every compiler I've ever used gives you the (extended) ability to declare bitfields in chunks of different widths (char, short, long, etc), but that is a non-standard capability. Also per standard, and despite the fact that bitfields are "ints", the signed-ness of a bitfield and whether or not to do sign extension is up to the implementation. There is no requirement by the language that you can store a signed quantity in a bitfield. Note that order of locating fields within that int is also up to the implementation. Some compilers will start with the LSB and work up, others with the MSB and work down. I developed the same philosophy as Andrew - bitfield portability and efficiency issues make them not worth using. I just define masks and use bitwise operators instead.
As already indicated in this forum, the behaviour on bitfields is implementation specific. In Keil C51, bitfields are always 'unsigned'. We recomment to avoid bitfields and use instead 8051 bits and bdata variables. Reinhard
Bit fields in C51 (and many other C's for that matter) are an exercise in inefficiency. Avoid them like the plague.