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
1073741824 is 0x40000000
- The 8-byte hexadecimal value of
3.14 is 0x40091EB851EB851F (in compliance with IEEE 754)
- By writing
0x40000000 into a[2], you have overridden the 4 least significant bytes in the 8-byte value of d[0] (without causing a segmentation fault), thus changing it from 0x40091EB851EB851F to 0x40091EB840000000, which stands for the (IEEE 754) floating-point value of 3.1399998664856
- By writing
0x40000000 into a[3], you have overridden the 4 most significant bytes in the 8-byte value of d[0] (without causing a segmentation fault), thus changing it from 0x40091EB851EB851F to 0x4000000051EB851F, which stands for the (IEEE 754) floating-point value of 2.0000006103516