2

This is what I write:

   const int MAX=100;

   int main (){
       int notas [MAX]={0};

The compiler says the following:

[Error] variable-sized object may not be initialized
[Warning] excess elements in array initializer

When I write MAX with #define MAX 100, it works. But I don“t understand what's the matter with doing it this way?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

3 Answers3

6

In this case

 const int MAX=100;

does not create a compile time constant, so the array is treated as VLA. By definition, VLAs can not be initialised, hence the error.

On the other hand, #define MAX 100 is a pre-processor macro, and based on the textual replacement property, it results in a compile time constant value of 100, then the array is not a VLA and can be initialized as per the initialization rules.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
3

This

   const int MAX=100;
int main (){
   int notas [MAX]={0};

is a declaration of a variable length array the size of which is determined at run-time because the declaration of the variable MAX is not a compile-time constant in C. Such arrays may not be initialized in declarations.

From the C Standard (6.7.9 Initialization)

3 The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

So you could write for example

   const int MAX=100;
int main (){
   int notas [MAX];
   memset( notas, 0, MAX * sizeof( int ) );

Otherwise you could use a compile time constant like

   enum { MAX=100 };
int main (){
   int notas [MAX]={0};
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

Despite the const in the declaration

const int MAX = 100;

MAX is not a constant expression (i.e., something whose value is known at compile time). Its value isn't known until run time, so the declaration of notas is treated as a variable-length array declaration, and a VLA declaration may not have an initializer (nor may a VLA be declared at file scope, nor may it be a member of a struct or union type).

With the preprocessor macro

#define MAX 100

all instances of the symbol MAX are replaced with the literal 100 after preprocessing, so it's effectively the same as writing

int notas[100] = {0};

which is why using the preprocessor macro works.

John Bode
  • 119,563
  • 19
  • 122
  • 198