Keil Logo

Compiler error when declaring array using constant

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Brian Szuter
Posted
9-Jun-2004 17:10 GMT
Toolset
C51
New! Compiler error when declaring array using constant
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];

I get the same error whether or not I use "code". I've worked around this by using
#define BUF_SIZE 40
but this isn't optimal for style, and debugging purposes.

Has anyone else seen this problem?
Read-Only
Author
Hans-Bernhard Broeker
Posted
9-Jun-2004 17:30 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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};

Note that this is a generic C issue unrelated to Keil tools, so this is not really the right place to discuss it.
Read-Only
Author
Brian Szuter
Posted
9-Jun-2004 18:18 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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.
Read-Only
Author
Andy Neil
Posted
9-Jun-2004 19:27 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
"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?
Read-Only
Author
Brian Szuter
Posted
9-Jun-2004 19:36 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
Both probably weren't strict ANSI C, but the compiler wasn't a C++ compiler nor was the style guideline for C++.
Read-Only
Author
Hans-Bernhard Broeker
Posted
11-Jun-2004 13:26 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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.
Read-Only
Author
Andrew Neil
Posted
9-Jun-2004 17:38 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
"but this isn't optimal for style"

So you prefer "style" over the language syntax rules, then...? ;-)
Read-Only
Author
Drew Davis
Posted
9-Jun-2004 18:01 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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];

const in ANSI C isn't really a compile-time constant as in many languages. It's a hint to the compiler that you intend not to overwrite the variable in question. The grammar does not allow a variable (even a const one) to occur as the size in an array declaration. It's a wart; we just have to grin and bear it.

As I recall, ANSI C also requires that actual storage be allocated for "consts". It's usually more efficient for the code generator to inline the const as an immediate value in an instruction, but a "const int" will usually turn into a reference to a value in some memory location, which increases both code size and time. C++ is a little smarter, and doesn't require consts to have storage if they don't actually need it.
Read-Only
Author
Andy Neil
Posted
9-Jun-2004 19:35 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
"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);
Clearly the consts here can't be indicating compile-time constants!

(They simply flag items that should not be modified at run-time).
Read-Only
Author
Neil Kurzman
Posted
9-Jun-2004 20:45 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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
Read-Only
Author
Jon Ward
Posted
10-Jun-2004 01:10 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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];

Jon
Read-Only
Author
Oleg Sergeev
Posted
10-Jun-2004 06:40 GMT
Toolset
C51
New! RE: Compiler error when declaring array using constant
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;
it says to compiler that the user needs with one byte in code memory which must be filled with number 40 in. Then this byte becomes the variable labeled "BUF_SIZE". Okay, it is not a problem for compiler. Now look at the next line:
BYTE Qbuf[BUF_SIZE];
By this line you say to compiler: allocate memory array which size is defined by variable BUF_SIZE. But compiler does not know how to read variables! They may be read/wrote only by program, at time when your code executes. The compiler itself just know about this variable but it cannot read its value. That's why it produces error message.

If you really need with constant data as well as with that array, so I may recommend you such way:
#define BUF_SIZE 40
const unsigned char code buf_size = BUF_SIZE;
BYTE Qbuf[BUF_SIZE];

Regards,
Oleg

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.