2

Can you define a constant using the const keyword in C.

I am finding conflicting information.

Used the #define macro and hard code the value to test. The code will compile in those cases but is throwing an error when I use the const keyword.

int main(void){

  const int  TESTARRAYSIZE = 7;
  float user_array[TESTARRAYSIZE] = {5.1, 7.2, 5.1, 8.45, 23.0,
                                       67.123, 5.1};
  float number_in_question = 5.1;

  float frequency;

  frequency = user_array[1];

  printf("%.2f", frequency);

  return(0);
}

compile error: <filename>:22:3: error: variable-sized object may not be initialized

but this error largely seems to be coming because the constant isn't setting the value.

hicksca
  • 65
  • 7
  • 3
    `const`-qualified variables are not constant expressions – M.M Jul 07 '19 at 03:17
  • I'm seeing this being explained otherwise in a few different places: https://www.tutorialspoint.com/cprogramming/c_constants.htm https://www.w3schools.in/c-tutorial/constants/ – hicksca Jul 07 '19 at 03:21
  • 7
    Those sites are wrong – M.M Jul 07 '19 at 03:23
  • 2
    This is one of the key differences between C and C++. `const`-qualified variables in C++ are true compile-time constants and can be used for things like array sizes, but this is *not* true in C. I suspect the misinformation you've seen stems from authors who assume that what they know about C++ is true for C (perhaps because they don't understand that the two languages are different). – Steve Summit Jul 07 '19 at 03:33
  • See also ["static const" vs "#define" vs "enum"](https://stackoverflow.com/questions/1674032/static-const-vs-define-vs-enum/). – Jonathan Leffler Jul 07 '19 at 05:24

2 Answers2

5

Using the const type qualifier doesn't make something a constant. A constant in C has its own definition.

See § 6.7.3 ¶ 6 of the C11 standard for a description of the const keyword:

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.

What you need there is a constant expression; see § 6.6 of C11 for details.

If what you're really wondering isn't "WTF is up with the const qualifier?" but rather what the right solution for your code is, the answer is likely to simply not specify the size of the array:

float user_array[] = {5.1, 7.2, 5.1, 8.45, 23.0, 67.123, 5.1};

This is generally considered good practice as it actually makes your code a bit more robust.

nemequ
  • 16,623
  • 1
  • 43
  • 62
  • 1
    No, the code doesn't matter. Just a little confused because I've seeing bad information on the use of contestants using keyword. This gives me a better place to start thank you. – hicksca Jul 07 '19 at 03:35
  • This is the best option, and conforms to every version of ISO C. Further, if you want to access the size, `const size_t user_array_size = sizeof user_array / sizeof *user_array;` and it will be updated automatically. – Neil Jul 07 '19 at 22:09
1

The compiler throws an error because when using stack memory the variables are allocated by the compiler in the pre-compilation stage, The size of the array must be a known value to the compiler in this stage

As you said if you #define the value there would be no error due to the fact it's a known hardcoded value.

  • 1
    In `C99`, one can have variable-length arrays, but `C11` made it a conditional feature. https://en.wikipedia.org/wiki/Variable-length_array – Neil Jul 07 '19 at 22:21
  • @Neil the array was more an artifact of the example. Thanks for the info though. – hicksca Jul 07 '19 at 22:27