views:

276

answers:

6

Why does the array a not get initialized by global variable size?

#include<stdio.h>

int size=5;

int main()
{
    int a[size]={1,2,3,4,5};
    printf("%d",a[0]);
    return 0;
}

The compilation error is shown as "variable-sized object may not be initialized".
According to me the array should get initialized by size. and what would be the answer if i insist on using global variable(if it is possible)

+7  A: 

You don't need to tell the compiler what size the array is if you're giving an initializer. The compiler will figure out the size based on how many elements you're initializing it with.

int a[] = {1,2,3,4,5};

Then you can even let the compiler tell you the size by getting the total size of the array in bytes sizeof(a) and dividing it by the size of one element sizeof(a[0]):

int size = sizeof(a) / sizeof(a[0]);
indiv
+3  A: 

It looks like that your compiler is not C99 Compliant...speaking of which, which compiler are you using? If it's gcc you need to pass the switch '-std=c99'.... if you are using a pre-C99 compiler, that statement is illegal, if that's the case, do this:

int main() { 
   int a[5]={1,2,3,4,5}; 
   printf("%d",a[0]); 
   return 0; 
}

In pre-C99 standard compilers, use a constant instead of a variable.

Edit: You can find out more about the C99 standard here... and here....

tommieb75
its gcc's latest version
CadetNumber1
So C99 allows `int a[size];` where size is a variable? I had no idea...
IVlad
In C99 you can declare a variable sized array, but you cannot then initialize it in this manner. The problem is exactly what the error message says.
Jeffrey L Whitledge
In this case, the problem is not VLAs support or not, it's providing an initializer to a vla - which is not allowed.
nos
That's very interesting, I had no idea you could do that. The post is a little misleading though, as it doesn't mention the problem is the initialization and not the declaration. Anyway, +1 for teaching me something new.
IVlad
The compiler is conforming (6.7.8/3).
Steve Jessop
+3  A: 

size is a variable, and C does not allow you to declare (edit: C99 allows you to declare them, just not initialize them like you are doing) arrays with variable size like that. If you want to create an array whose size is a variable, use malloc or make the size a constant.

IVlad
+4  A: 

The compiler cannot assume that the value of size is still 5 by the time main() gets control. If you want a true constant in an old-style C project, use:

#define size 5
Seva Alekseyev
A: 
#include<stdio.h> 

/* int size=5; */
#define size 5 /* use this instead*/
/*OR*/
int a[size]={1,2,3,4,5};  /* this*/

int main() 
{ 
    int a[size]={1,2,3,4,5}; 
    printf("%d",a[0]); 
    return 0; 
} 

int size means that size is a variable and C does not allow variablesize arrays.

I am using VS2008 where using

const int size=5;  

allows

int a[size]={1,2,3,4,5}; 
TheMachineCharmer
why can't i use global variables?
CadetNumber1
@ashish: because global variables are still variables (the clue's in the name). Suppose somebody assigned the value `1` to `size` somewhere before your code to define `a`. Then you'd be trying to initialize an array of size 1 with an initializer list of size 5. Rather than trying to sort this mess out, the standard forbids it.
Steve Jessop
thanks for that steve
CadetNumber1
+8  A: 

In C99, 6.7.8/3:

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

6.6/2:

A constant expression can be evaluated during translation rather than runtime

6.6/6:

An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts.

6.7.5.2/4:

If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

a has variable length array type, because size is not an integer constant expression. Thus, it cannot have an initializer list.

In C90, there are no VLAs, so the code is illegal for that reason.

In C++ there are also no VLAs, but you could make size a const int. That's because in C++ you can use const int variables in ICEs. In C you can't.

Presumably you didn't intend a to have variable length, so what you need is:

#define size 5

If you actually did intend a to have variable length, I suppose you could do something like this:

int a[size];
int initlen = size;
if (initlen > 5) initlen = 5;
memcpy(a, (int[]){1,2,3,4,5}, initlen*sizeof(int));

Or maybe:

int a[size];
for (int i = 0; i < size && i < 5; ++i) {
    a[i] = i+1;
}

It's difficult to say, though, what "should" happen here in the case where size != 5. It doesn't really make sense to specify a fixed-size initial value for a variable-length array.

Steve Jessop
+1 for quotes :)
Tom