mmccomb
mmccomb

Reputation: 13807

The const modifier in C

I'm quite often confused when coming back to C by the inability to create an array using the following initialisation pattern...

const int SOME_ARRAY_SIZE = 6;
const int myArray[SOME_ARRAY_SIZE];

My understanding of the problem is that the const operator does not guarantee const-ness but rather merely asserts that the value pointed to by SOME_ARRAY_SIZE will not change at runtime. But why can the compiler not assume that the value is constant at compile time? It says 6 right there in the source code...

I think I'm missing something core in my fundamental understanding of C. Somebody help me out here. :)

[UPDATE]After reading a bit more around C99 and variable length arrays I think I understand this a bit better. What I was trying to create was a variable length array - const does not create a compile time constant but rather a runtime constant. Therfore I was initialising a variable length array, which is only valid in C99 at a function/block scope. A variable length array at the file scope is impossible as the compiler cannot assign a fixed memory address to an unbounded array.[/UPDATE]

Upvotes: 6

Views: 6956

Answers (5)

Paul R
Paul R

Reputation: 212949

You can do this in C99, and some compilers prior to C99 also had support for this as an extension to C89 (e.g. gcc). If you're stuck with an old compiler that doesn't have C99 support though (e.g. MSVC) then you'll have to do it the old skool way and use a #define for the array size.

Note that that above comments apply only to such declarations at local scope (i.e. automatic variables). C99 still doesn't allow such declarations at global scope.

Upvotes: 1

Lindydancer
Lindydancer

Reputation: 26094

The const keyword is basically a read-only indication. It does not, really, indicate the underlying value will not change, even though that is the case in your example.

When it comes to pointers, this is more clear:

void foo(int const * p)
{
  if (*p == 100)
  {
    bar();
    /* Here, the compiler can not assume that *p is 100 */
  }
}

In this case, a compiler should not accept the code in your example, as it requires the array size to be constant. If it would accept it, the user could later run into trouble when porting the code a more strict compiler.

Upvotes: 2

Armen Tsirunyan
Armen Tsirunyan

Reputation: 132984

Well, in C++ the semantics are a bit different. In C++ your code would work fine. You must distinguish between 2 things, const and constant expression. Const means simply, as you described, that the value is read-only. constant expression, on the other hand, means the value is known compile time and is a compile-time constant. The semantics of const in C are always of the first type. The only constant expressions in C are literals, that's why #define is used for such kind of things.

In C++ however, any const object initialized with a constant expression is in itself a constant expression.

I don't know exactly WHY this is so in C, it's just the way it is

Upvotes: 5

Joris
Joris

Reputation: 6286

i just did a very quick test with my Xcode and Objective C file I currently had open on my machine and put this in the .m file:

const int arrs = 6;
const int arr[arrs];

This compiles without any issues.

Upvotes: 0

James Anderson
James Anderson

Reputation: 27478

The problem is that the language syntax demands a integer value between the [ ]. SOME_ARRAY_SIZE is still a variable (even if you told the compiler nobody is allowed to vary it!)

Upvotes: 4

Related Questions