Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does overflowing array initialization give warning but overflowing assignment does not?

Tags:

arrays

c

Why does int a[5] = {1,2,3,4,5,6} give a warning while int a[5] = {1,2,3,4,5}; a[5] = 6; does not?

Is it a good practice to do this when I initially declared the array size to be 5?

What if I don't know the size of my array? Can I declare it like this int a[]?

like image 962
mushroom Avatar asked Dec 02 '22 19:12

mushroom


2 Answers

Why does int a[5] = {1,2,3,4,5,6} give a warning while int a[5] = {1,2,3,4,5}; a[5] = 6; does not?

The assignment gives you a warning because you know the size of the variable in the initialization statement, and it is obviously violating the size of your declaration. You don't have the size of the array from a in the line a[6] = 6, so for the compiler it seems ok. Of course the level of warnings change from compiler to compiler, and for some compilers you can specify extra warnings.

For example, using gcc, you could use the flags -Wextra and -Wall to get a lot of warnings. Receiving warnings is a good thing, because the compiler helps you to find possible caveats without needing to debug your code. Of course, they are only good if you fix them :-)

Is it a good practice to do this when I initially declared the array size to be 5?

It is never a good practice to assign an integer to a place in memory that you didn't declare - you can't be sure where this value is being written, and it can be overwriting another variable, or worse, partially overwriting some other variable or the stack. Since this kind of stuff is different from compiler to compiler, as @PascalCuoq pointed out, it is called undefined behavior, and is something you want to avoid at all costs. Of course, since it is undefined, it can happen that your program will execute just fine after this declaration, yet it is a very poor practice.

However, there is nothing wrong with initializing an array with fixed size, if it will not change. You should avoid magic numbers and use constants instead, like MAX_NUMBER_OF_PERMUTATIONS or CURRENCIES_SIZE, for instance.

Can I declare it like this: int a[]?

Declaring it as int a[] is a shorthand when you are initializing a fixed array and the compiler can specify the number of elements. For example:

int a[] = {1,2,3}; //this is good
int b[3] = {1,2,3}; //same from above

In the past it was usual declare int a[]; however it don't works in every compiler, so should be avoided. (Thanks @PascalCuoq for pointing this out)

What if I don't know the size of my array?

If you don't know the size of your array, you should declare it as a pointer, like int * a and manage the memory yourself using malloc, realloc, calloc and similar system calls. Please do a good job and learn about free too - the world will thank you later. You should read about pointers instead of arrays if you are looking for dynamic memory allocation.

like image 77
fotanus Avatar answered Dec 29 '22 07:12

fotanus


Why does int a[5] = {1,2,3,4,5,6} give a warning while int a[5] = {1,2,3,4,5}; a[6] = 6; does not?

Warnings are only the compiler trying to help you. The compiler does not have to warn everytime you do something wrong. There are too many ways to write incorrect programs, and compilers cannot warn for all of them.

Is it a good practice to do this when I initially declared the array size to be 5?

No. When a is an array of size 5, accessing a[6] or a[5] invokes undefined behavior (translation: it is very bad). The traditional saying about undefined behavior is that it allows the compiler to make daemons fly out of your nose:

During a discussion on that group in early 1992, a regular remarked “When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose” (the implication is that the compiler may choose any arbitrarily bizarre way to interpret the code without violating the ANSI C standard).

So, in short, always avoid undefined behavior in your C programs.

What if I don't know the size of my array? Can I declare it like this int a[]?

No, you can't. You have to know the size of your array when you declare it. int a[]; would declare an incomplete array, which is not what you want (here is a link about incomplete types, but if you are asking about accessing the sixth element of a five-element array, you just don't want to hear about incomplete types yet). If you do not know the size you will eventually need, learn about malloc() and realloc().

like image 34
Pascal Cuoq Avatar answered Dec 29 '22 09:12

Pascal Cuoq