We are currently in the process of evaluating Keil tools for possible purchase. Using the evaluation package, I have been checking some common functions. One of them is a simple bit test macro suitable for a large variable where speed is not important. #define BTST(VAR, BITPOS) ((VAR) & (1<<(BITPOS))) I used this in the following manner unsigned long temp; unsigned char shift; BTST(temp, shift); The Keil C51 compiler generates the following: MOV A,#01H MOV R6,#00H MOV R0,shift?143 INC R0 SJMP ?C0015 ?C0014: CLR C RLC A XCH A,R6 RLC A XCH A,R6 ?C0015: DJNZ R0,?C0014 MOV R7,A MOV A,R7 ANL A,temp?144+03H MOV R7,A Note that even though I have ANSI promotions enabled, it does not promote the unsigned character to a long. It appears to promote it to an integer (using A and R6 for the data), but then never uses the MSB (R6) when performing the AND operation. I have even tried this: BTST(temp, (unsigned long) shift); and I get the same results. I have used this macro with many other compilers with complete success, following what I understand about integral promotion in ANSI C. There seem to be several threads about bit-fields and the like, but none seemed to deal with integers or longs or shift operations. Any thoughts? Thanks much in advance, Peter
Hi Peter, The 'unsigned char shift' doesnt need to be promoted to a long because it is just used to generate a mask '2**shift' internaly by the compiler and as such 'shift' should not exceed 31 (for a 32bit no.). If anything it doesnt look like the compiler is generating a 4 byte mask so it might be better to try and cast VAR as long in your macro (but this will be inefficient for char/int variables) to ensure that it works thus, #define BSTS(VAR, BITPOS) ( ((unsigned long)VAR) & (1 << BITPOS) ) Hope this helps, Mark.