Hi,
I hope someone can help. Code with comments explaining the problem is shown below.
char const char_set1[42] = {'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z','.','-','%','/',':','0', '1','2','3','4','5','6','7','8','9',' '}; [I then wish to declare a constant pointer to the array] [The following declaration compiles:] char const* char_set_arrayA = char_set1; [But the following declaration fails:] char const* char_set_arrayB[]={char_set1};
Eventually I need to pass a series of character set arrays into this declaration but I cannot get it to compile with one array element (char_set1).
I would be grateful for any advice as to why
char const* char_set_arrayB[]={char_set1};
is not accepted by the compiler. The compiler reports
"error #28: expression must have a constant value"
Is the const declaration incorrect?
Thanks
John McLane
const char *char_set_arrayB = char_set1 ;
?
One thing to think about here: Is it the value of the pointer that is constant, or is it the data the pointer points to that may not be changed? This is controlled by the location of the const keyword in the declaration.
It compiles for me. And I can see no reason why it wouldn't compile. What compiler are you using?
- mike
The pointer is constant. The data in the array is constant and the arrays are constant.
I've tried all of the following. They all fail with the same #28 error message.
const char *char_set_array[] = {char_set1}; const char * const char_set_array[] = {char_set1}; char const* const char_set_array[] = {char_set1}; char* const char_set_array[] = {char_set1}; char* char_set_array[] = {char_set1};
Eventually I need to addd further elements to the array {char_set1,char_set2,char_set3,char_set4} and am simply trying to get it to compile with one element.
I am using the following compiler/toolset
IDE-Version: µVision3 V3.63 Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 - 2008
License Information:
Tool Version Numbers: Toolchain: RealView MDK-ARM Version: 3.24 Middleware: RL-ARM Real-Time Library Version V3.24 Toolchain Path: BIN31\ C Compiler: Armcc.Exe V3.1.0.939 Assembler: Armasm.Exe V3.1.0.939 Linker/Locator: ArmLink.Exe V3.1.0.939 Librarian: ArmAr.Exe V3.1.0.939 Hex Converter: FromElf.Exe V3.1.0.939 CPU DLL: SARM.DLL V3.24 Dialog DLL: DARMST9.DLL V1.06 Target DLL: BIN\UL2ARM.DLL V1.43 Dialog DLL: TARMST9.DLL V1.03 Thanks
You probably want the array of pointers to be constant too, but that shouldn't cause a compiler error. Can you try to compile the very minimal source?
char const chars[] = { 'a', 'b' }; char const* const ptrs[] = { chars };
I mean just the two lines, no includes or anything. See if the compiler complains. Mine doesn't, and it's v3.1.0.939 (same as yours.) Maybe you have a macro somewhere that distorts your code in an unexpected way?
Thanks Mike. That's interesting.
I compiled your suggested code in a single file. It compiles fine with just the two lines. No errors.
However, the moment I put it in a simple void function as follows it fails with the same #28 error appears.
void test(void) {
}
However, the moment I put it in a simple void function as follows it fails
This one's easy. If chars is an automatic variable, its address is not constant any more and cannot be used as an array initializer. Make it static, and it will work again. It makes sense. An automatic variable is usually placed on the stack, so you cannot know its address before the function is called, so the address is not constant. I'm sure the language standard covers this, but it would take too much time to look it up...
You shouldn't consume stack - or even RAM - for a const table.
So what you are trying to do is build an array to pass it to a function? That's why you put the array declaration inside a function? If that's true, then it's clear what's happening. A scalar automatic variable can be initialized by a non-constant value. That's why 'char const* char_set_arrayA = char_set1;' works. On the other hand, an array must be initialized by constant values only (if I remember correctly, the language standards mandates this.) So there you have it. Apart from language issues, there is the issue of memory consumption. You can make the arrays constant and static, and they will consume only ROM. On the other hand, if you make them automatic, they will consume stack space, and not at the expense of ROM usage but as an extra.
It compiles using static</b?
I had no idea that const variables would be put on the stack.
A lack of understanding on my part.
Thanks Mike.
not at the expense of ROM usage but as an extra
I'm sorry, English is not my first language. I know what I meant, and this is probably not it. I hope no-one got confused by this :-)
const _only_ says that you may not modify the variable.
It is up to the compiler to decide if it can optimize further by storing the data in the flash instead of creating a RAM copy.
A const parameter is an example where the compiler does not have any option: it must send the parameter value on the stack, unless the calling convention uses registers or global variables for the transfer.