Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

valid and invalid syntax for representing the size of array during initialisation

Tags:

arrays

c

I'm currently studying c array and is confused about what can and can't be used to represent the size of the array during initialisation.

Am I right to assume

#define SIZE 5 

and

const int SIZE = 5; 

are fundamentally different to one another?

They have their difference and one particular example that confuses me is

#define SIZE 5
int arr[SIZE] = {11, 22, 33, 44, 55}; 

is valid syntax, but

const int SIZE = 5;
int arr[SIZE] = {11, 22, 33, 44, 55};

is not valid syntax. Though interestingly,

const int SIZE = 5;
int arr[SIZE];

is valid syntax.

What's the logic behind whether a particular syntax is valid or invalid?

like image 703
Thor Avatar asked Feb 26 '18 03:02

Thor


People also ask

What is the valid syntax for initializing an array in the C programming language?

The following syntax uses a “for loop” to initialize the array elements. This is the most common way to initialize an array in C. // declare an array. int my_array[5];

What is array How do you declare and initialize it?

To initialize or instantiate an array as we declare it, meaning we assign values as when we create the array, we can use the following shorthand syntax: int[] myArray = {13, 14, 15}; Or, you could generate a stream of values and assign it back to the array: int[] intArray = IntStream.

What is the array and initializing arrays?

Single Dimensional Array Initialization. The process of assigning values to the array elements is called array initialization. Once an array is declared, its elements must be initialized before they can be used in the program. If they are not properly initialized the program produces unexpected results.


1 Answers

Am I right to assume

#define SIZE 5
and
const int SIZE = 5;

are fundamentally different to one another?

Yes, you are right.

#define is simply a textual replacement. Basically, the C preprocessor is going a "find and replace" for you during the compilation process (processing stage). Whereas, const qualified object means "the thing stored at this location can't changed" - roughly equivalent to saying it's "read-only".


#define SIZE 5
int arr[SIZE] = {11, 22, 33, 44, 55};

is valid syntax.

This is exactly equivalent to writing:

int arr[5] = {11, 22, 33, 44, 55}; 

yourself. The compiler simply does the replacement job for you when you use define.


const int SIZE = 5;

int arr[SIZE] = {11, 22, 33, 44, 55};

is not valid syntax.

It's invalid but the reason could be more than one. If arr has static storage duration (i.e., the object arr is alive throughout the program execution) then it's invalid. Because C requires that the size of an array object with static storage duration to be a constant expression:

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.

So, the following program is not valid:

const int SIZE = 5;
int arr[SIZE] = {11, 22, 33, 44, 55};
int main(void)
{
}

because SIZE doesn't qualify as a "constant expression" in C. Note that this is totally valid in C++ where SIZE qualifies as a constant expression (the two languages differ here).

Another reason is C standard doesn't allow initializing variable-length arrays. If you have the definition inside a function such as:

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 if you don't have the initializer then it becomes valid:

int main(void)
{
    const int SIZE = 5;
    int arr[SIZE];  /* This is OK */
}

Similarly, you can do without the const as well:

int main(void)
{
    int SIZE = 5;
    int arr[SIZE]; /* Thi is OK too. */
}

In both of the above snippets, arr is simply a variable-length array.

Though interestingly,

const int SIZE = 5; int arr[SIZE];

is valid syntax.

It's valid only if it's inside a function (as above) - it's a VLA. But if you make it have static storage duration such as:

const int SIZE = 5;
int arr[SIZE]; /* arr has static storage duration just as
                 all objects defined at file scope */

int main(void)
{
}

it's invalid because as noted above, SIZE is not a "constant expression" in C.

Similarly,

int main(void)
{
    const int SIZE = 5;
    static int arr[SIZE]; /* arr has static storage duration */
}

is invalid for the same reason, despite arr being inside a function, because arr has static storage duration.


However, if you have:

enum {SIZE = 5};
int arr[SIZE] = {11, 22, 33, 44, 55};
 int arr2[SIZE]; /* Valid without initializer too. */

int main()
{
}

it's valid. Why? Because enum constants qualify as "constant expressions" in C.

like image 157
P.P Avatar answered Oct 20 '22 02:10

P.P