I run into a problem using enum datatype with printf statement. The folloing code works with Viusal C but does not work with KEIL compiler --- printf statement prints out the wrong value. Could somebody in this forum tell me what I did wrong here? --- here is the test code
enum MONTHS {JAN=1,FEB,MAR,APR,MAY,JUN,JUL, AUG,SEP,OCT,NOV,DEC} birthday; void main(void) { birthday = NOV; printf("\n\r\ My birthday = %d", birthday); }
Per the ANSI standard, a C "int" has to be at least 16 bits wide. An 8-bit processor would naturally prefer 8-bit values where possible. Keil C51 has a few extensions to allow you to use 8 bit values for greater efficiency. One of these extensions means that they do not automatically "promote" 8-bit values to "ints" when passed as parameters. (See "ANSI integer promotion" in the manual.) As a result, a variable-arg function like printf() needs a format specifier for a value that's 8 bits wide, and not just for ints. %d is the standard format specifier for an int (decimal). %ld is the standard format specifier for a "long int". This lets printf() know that the amount of data in the parameter list is perhaps longer than just for a %d int. %bd is the Keil format specifier for a "byte int". This lets printf() know that the amount of data in the parameter list is less than that for a %d int. If you tell printf that there's a %d in the parameters, but actually pass in a 8-bit value, the print routine will pull out two bytes, not just one, and all the printed data gets misaligned and comes out garbled.
"Could somebody in this forum tell me what I did wrong here?" You assumed that you could just take any piece of 'C' code from one compiler to another without any consideration of the implementation-specific issues. In particular, you have taken code from a large 32-bit desktop system and dumped it onto a small, specialist embedded 8-bit target! http://www.8052.com/forum/read.phtml?id=110880
Hi Dan, It works now. Thank you for your help. JIMMY
Please review: http://www.keil.com/support/man/docs/c51/c51_ap_1bytescalar.htm and http://www.keil.com/support/man/docs/c51/c51_printf.htm Then decide whether you want:
printf("\n\r\ My birthday = %d", (int)birthday);
printf("\n\r\ My birthday = %bd", birthday);
View all questions in Keil forum