7

I've found an interesting fact, and I didn't understand how is it works.

The following piece of code just works perfectly.

#include <stdio.h>

int main() {
  const int size = 10;
  int sampleArray[size];
  typedef char String [size];
  return 0;
}

Then, I tried to use only and only the constant variable with a global scope, and it's still fine.

#include <stdio.h>

const int size = 10;

int main() {
  int sampleArray[size];
  typedef char String [size];
  return 0;
}


But, if I change the arrays's scope to global as well, I got the following:

error: variably modified ‘sampleArray’ at file scope

#include <stdio.h>

const int size = 10;
int sampleArray[size];

typedef char String [size];

int main() {
  return 0;
}

And I didn't get it! If I'd replace the const variable for ex. to #define it'd be okay as well.
I know that the #define variable is preprocessed, and as far as I know the const variable is only read-only. But what does make the global scope after all?

I don't understand what is the problem with the third piece of code, if the second one is just okay.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bálint Pap
  • 498
  • 2
  • 12
  • 23
  • 3
    Some detail: C has `const` objects but not _constant_ ones. Although `const` seems to implies _constant_, a `const` object is not _constant_, but more like "this object should not change, but if a change is attempted - who knows what might happen?" In C, a true _constant_ is code like `42`, which is an _integer constant_ with the type of `int`. Thus `const int size = 10;` is not a _constant_ variable. – chux - Reinstate Monica Nov 14 '16 at 23:21
  • The array has no constant size, but is a variable length array. – too honest for this site Nov 15 '16 at 08:36
  • 1
    Like they said, C has `const` objects, which are actually read-only *variables*. Cf. C++, which has true `const` objects that are actually compile-time *constants*. – David R Tribble Nov 15 '16 at 16:24
  • 1
    a `const` variable is a variable that the compiler doesn't allow to be modified, but a variable. Think that value can be unknown at compilation time (as it can come from other file) but the array size must be, so it is forbidden. – Luis Colorado Nov 17 '16 at 16:37
  • Alternative duplicate: *[Variably modified array at file scope in C](https://stackoverflow.com/questions/13645936/variably-modified-array-at-file-scope-in-c)*. – Peter Mortensen Jul 29 '23 at 09:38

1 Answers1

7

Variable-length arrays (VLAs) may have only automatic storage duration. VLAs were introduced in C99.

It is not allowed to declare a VLA with the static storage duration because the size of VLA is determined at the run time (see below).

Before this Standard, you can use either a macro like

#define SIZE 10

//...

int a[SIZE];

or a enumerator of an enumeration like

enum { SIZE = 10; }

//...

int a[SIZE];

By the way, you may remove the const qualifier and just write

int size = 10;

instead of

const int size = 10;

(In C++ you have to use the const qualifier though. In C++, there aren't any VLAs, except that some compilers can have their own language extensions.)

Take into account that the sizeof operator for VLAs is calculated at the run time instead of the compile time.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you I've just started to understand a bit more! However, if I trying without the const, I've got the same error with global scope. But with the #define SIZE 10, it's works. – Bálint Pap Nov 14 '16 at 23:02
  • @BálintPap As I wrote VLAs may not have static storage duration that all global arrays have. – Vlad from Moscow Nov 14 '16 at 23:03
  • A, here we go, alright! Well, never thought about that. Thank you for your explanation! I do appreciate it! – Bálint Pap Nov 14 '16 at 23:07