I wrote a simple program below which calculates the sum and return the result to main(). The main() then calculates the average. SumOfArray() expects float but I am passing an array of integers. I expected that the integers would be converted into float type implicitly. i.e 35 would be passed as 35.0 but to my surprise it was 0. the short explanation from whatever I could find is that the behavior is undefined because in this case the typecast happened not from (int)->(float) but (int*)->(float*)
However why does the function SumOfArray() see 0 instead of actual integers if it is reading from the same location. I checked this by printing the address of array both in main() and SumOfArray(). They were same.
Is there anything specific about this mentioned in ISO C standards? The size of integer and float on my machine is 4 bytes so I expected it would read same values albeit with loss of precision.
Following is my program. I printed the values of array passed to the function in SumOfArray.
I am using gcc compiler , codeblock ide compiling for x86_64. Tried this on debian as well.
#include<stdio.h>
float SumOfArray(const float array[],unsigned int size)
{
float sum=-1.0;
if(size!=0&&array!=0)
{
sum=0;
for(int i=0;i<size;i++)
{
sum+=array[i];
printf("sum in sum of array is%f\n",sum);
printf("array[%d] is %f\n",i,array[i]);
}
}
return sum;
}
int main()
{
int gradesI[]={35,56,88,23,45,99};
unsigned int sizeI = sizeof(gradesI)/sizeof(int);
float sumI = SumOfArray(gradesI,sizeI);
printf("the sum of is %f\n",sumI);
float average = sumI/sizeI;
printf("the average is %f\n",average);
return 0;
}
- *output*
sum in SumOfArray is 0.000000
**array[0] is 0.000000**
sum in SumOfArray is 0.000000
**array[1] is 0.000000**
sum in SumOfArray is 0.000000
**array[2] is 0.000000**
sum in SumOfArray is 0.000000
**array[3] is 0.000000**
sum in SumOfArray is 0.000000
**array[4] is 0.000000**
sum in SumOfArray is 0.000000
**array[5] is 0.000000**
the sum of is 0.000000
the average is 0.000000
You are not passing a int
but a pointer to int
(decayed from a array of int
) and you don't expect a float
but a pointer to float
.
What you have in memory gradesI
:
+------+------+------+------+-
| int | int | int | int | ...
+------+------+------+------+-
When you call a function with gradesI
as argument, it decays to a pointer to int
, a pointer that points to gradesI[0]
.
What SumOfArray()
expects the pointer pointing to in memory
+------+------+------+------+-
| float| float| float| float| ...
+------+------+------+------+-
What you ask is why the int
array isn't converted automatically to a float
array. There are multiple reasons:
In c only the argument itself (i.e. the pointer) gets converted. A pointer to int
shouldn't be implicitly converted to a pointer to float
, because you can't access a int
through a float
pointer (when you try it you get undefined behaviour).
The compiler would have to generate a new temporary array and passing a pointer to the new temporary array. But that would break a lot of code since we expect the pointer in the function to point to the same location as in the caller.
The compiler doesn't know how many int
's it should convert to float
.
Even if the compiler knows that, it would be time consuming.