You declare an array of 2 entries:
volatile long int a[2];
You then access this array with an index:
a[i] = 1073741824;
Since array-indexing in C starts at 0, any index larger than 1 would yield undefined behavior.
In your program, you are calling the function with indexes i=2, i=3 and i=4.
Each one of these function calls independently yields undefined behavior.
Undefined behavior means that anything can happen.
The fact that you're experiencing a segmentation fault only upon fun(4) is a mere coincidence.
Supplemental:
Disclaimer: the following analysis does not imply that the same behavior is to be expected on every platform, or even on every execution; it is merely in order to explain the "odd" return-values observed.
- The 4-byte hexadecimal value of 1073741824is0x40000000
- The 8-byte hexadecimal value of 3.14is0x40091EB851EB851F(in compliance with IEEE 754)
- By writing 0x40000000intoa[2], you have overridden the 4 least significant bytes in the 8-byte value ofd[0](without causing a segmentation fault), thus changing it from0x40091EB851EB851Fto0x40091EB840000000, which stands for the (IEEE 754) floating-point value of3.1399998664856
- By writing 0x40000000intoa[3], you have overridden the 4 most significant bytes in the 8-byte value ofd[0](without causing a segmentation fault), thus changing it from0x40091EB851EB851Fto0x4000000051EB851F, which stands for the (IEEE 754) floating-point value of2.0000006103516