2

I read everything and everywhere I could about "compile time constants" in C, and I cannot yet give an explanation to the following:

const short testArray[2]={1,2};
//void IndeedConst(void){ testArray[0]=3; } //correctly reports "error: assignment of read-only location 'testArray[0]'"
const short testItem=testArray[0]; //why "error: initializer element is not constant"??

so the compiler is complaining that testArray[0] is read only/const and at the same time it is stating that testArray[0] is not constant! I did answer myself "evidently the dereferencing operator [ ] cannot work "on compile time" constant initialization, then whyever this lines would compile with no errors?

const short* testItem=&(testArray[1]);

also note that here I am getting the address of the 2nd item in the array. therefore the "compile time" constant initialization can dereference with no problem!
What's an explanation for this?

9
  • 1
    const short testItem=testArray[0]; shouldn't produce an error. Please post an MCVE. Commented Feb 1, 2015 at 14:46
  • @mafso Not for me with clang 3.5 in c89, c99 or c11 mode. Similarly with gcc. What compiler and C standard are you compiling with? Commented Feb 1, 2015 at 14:49
  • @mafso To clarify: I know this is C. I never said anything about C++. Commented Feb 1, 2015 at 14:57
  • 1
    @juanchopanza It won't compile if the variables have static storage duration (i.e. if they are globals or static locals). Commented Feb 1, 2015 at 15:00
  • 1
    OK, got it. I thought your variables were automatic, and they are static. That makes a difference in C. Commented Feb 1, 2015 at 15:03

1 Answer 1

4

For variables with static storage duration, the initializer must consist of constant expressions. These include:

  • An arithmetic constant expression: This can only have operands that are integer/enum/character/floating constants, and sizeof expressions. They may not refer to the values of other variables.
  • A null pointer constant.
  • An address constant, optionally added to an integer constant expression. This address constant can be null, point to a function, or point to an object with static storage duration. The standard allows using operators such as [] and & as long as you do not refer to the value of an object.

In this case, testArray[1] is not a constant expression due to referring to the value stored in another variable, but &testArray[1] is an address constant and is a valid constant expression.

Reference: C99 standard, section 6.6.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much, this is what I understood: the initializer CAN NOT contain const variable (such as testArray[0]), although they are const and static (that's not so intuitive); the [..] operator in the second definition (&testArray[1]) works simply because it stands for &testArray + 1, that is 'optionally added to an integer constant expression' (again not so intuitive); finally explained something worrying me for hours, thanks again!
Just a final note: don't you think the compiler response "error: initializer element is not constant" is completely misleading? the initializer element IS constant! the point is that it is not a valid initializer (being a const variable)
@VittorioG. It's confusing, but they are using the word "constant" to mean a constant expression as described above. The keyword const marks a value as non-modifiable in runtime and it is not considered "constant". The reason for this confusing wording is that C originally had no const keyword, so the only meaning of "constant" was as described above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.