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
There are several problems with your test code. 1. BTST(temp, shift); This does nothing with the results. Therefore, the compiler does not have to generate any code at all since no variables are affected! 2. The size of an int in the Keil compiler is 16 bits. With ANSI integer promotion enabled, here's what happens in the MACRO: A. BTST(temp, shift) is expanded into
((temp) & (1<<(shift))
#define BTST(VAR, BITPOS) ((VAR) & (1L<<(BITPOS))) void main (void) { unsigned long temp; unsigned char shift; volatile unsigned long junk; junk = BTST(temp,shift); while (1); }
Firstly, I apologize for including only a code snippet that could not be directly plugged into the compiler. Of course, the details I omitted were critical, thanks for showing me how to get this to work. The result that I was storing into was character length. The compiler was optimizing out the unneeded bytes. I hadn't even noticed this (I was thinking the result was a long) until your message made me look over the code again. I would also like to say that although the result of this exercise was a stupid mistake on my part, it wasn't a total waste of anyone's time as it has shown the support group on this message board to be execellent, which is also a critical part of evaluating these tools we are considering purchasing. I look forward to posting more stupid questions... Thanks Mark and Jon, Peter
I look forward to posting more stupid questions... And I'm sure there are many of us who look forward to answering them. ;-) Seriously, though. Thanks for the thanks. Jon