The following code generates a this error when compiled: C51 COMPILER V6.02 - SN: XXXXX-XXXXX COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 1999 *** ERROR C221 IN LINE 7 OF QUEUE_I.H: non-constant case/dim expression
const unsigned char code BUF_SIZE = 40; BYTE Qbuf[BUF_SIZE];
#define BUF_SIZE 40
Your problem is that your "constant" isn't actually a constant. It's a variable flagged "const", which is a rather different thing. The only other major alternative to #define to create an actual constant (what the C standard calls a "compile-time constant expression") is to make it an enum label, i.e.
enum {BUF_SIZE = 40};
"but this isn't optimal for style" So you prefer "style" over the language syntax rules, then...? ;-)
The third major alternative for declaring integer constants is to use an enum. This is of course most useful for grouping a related series of constants, rather than individual ones. But enum values can be used to size arrays:
typedef enum { ThingOne, ThingTwo, NumThings } Thing; U16 thingRefCount[NumThings];
I was surprised since other compilers compiled the const version without errors (GNU X-Tools for one). In addition, I've read Good Style practices that recommended using const rather than #define, so I wouldn't expect using it to violate ANSI C rules.
"I was surprised since other compilers compiled the const version without errors (GNU X-Tools for one)." I you sure that they were all 'C' compilers - not C++? Also, are you sure that you tried this in their strict ANSI mode? "In addition, I've read Good Style practices that recommended using const rather than #define" Again, are you sure they were specifically for 'C' - rather than C++, or any other language?
"const in ANSI C isn't really a compile-time constant" As is obvious from a quick look at at string.h:
extern char *strchr (const char *s, char c); extern int strpos (const char *s, char c); extern char *strrchr (const char *s, char c); extern int strrpos (const char *s, char c);
Both probably weren't strict ANSI C, but the compiler wasn't a C++ compiler nor was the style guideline for C++.
BYTE Qbuf[BUF_SIZE]; BUF_SIZE must be constant not a constant variable. It must be fix at compile time. the const keyword does not mean it can not be changed. Therefore thier can not be a style that would suggest a const. further more. Overusing of "Style" may result in extra ram / rom usage. your program need to be organize and read able, but not a slave to fashion. Remember just because Keil got C to fit into an 8bit Cpu does not mean you can forget it is an 8bit Cpu
Here's an interesting question (for those who consider const to be the same as #define). How many bytes are reserved for Qbuf in the following C code?
extern const unsigned char BUF_SIZE; BYTE Qbuf[BUF_SIZE];
hi, your problem is that you try to use the value of program variable as a number for the compiler process. See, what does next line do:
const unsigned char code BUF_SIZE = 40;
BYTE Qbuf[BUF_SIZE];
#define BUF_SIZE 40 const unsigned char code buf_size = BUF_SIZE; BYTE Qbuf[BUF_SIZE];
In addition, I've read Good Style practices that recommended using const rather than #define Then get back to whoever wrote them and challenge them about this aspect --- they must either be talking about programming languages similar in syntax to C, but different (Java or C++, e.g.), or they simply don't know what the heck they're talking about, and should refrain from handing out advice to others. The loop-hole that let GCC compile this code is that it (and the C99 standard now, too) allow variable-size arrays. But for most practical purposes, good C programming style these days is still based on C89+addenda, not C99.