Reputation: 61
today,I write some code to test unsigned int.
#include <stdio.h>
int sum_element(float ele[], unsigned int len);
int main(void){
float ele[] = {1.1,2.2,3.3};
float sum = sum_element(ele,3);
printf("sum is %f\n",sum);
return 0;
}
int sum_element(float ele[], unsigned int len){
int sum=0.0; //mistake,should be : float sum = 0.0
int i=0;
for(i=0;i<= len-1;i++){
printf("sum=%f, i=%d\n",sum,i);
sum += ele[i];
}
return sum;
}
in this example, i have a mistake, the type of variable sum, should be float, but i write int, the compile command:
gcc test.c -o test
and i run this code
./test
the output of the function sum_element is:
sum=0.000000, i=1
sum=0.000000, i=1
sum=0.000000, i=1
and then i found the mistakes, and i change the type of sum to float, then compiled again, and when i run it, the output is :
sum=0.000000, i=0
sum=1.100000, i=1
sum=3.300000, i=2
this time, the output like normal,but in first output, why the variable of i is always the same value of 1, can someone tell me?
Upvotes: 2
Views: 142
Reputation: 5615
You have to understand how va_arg work. Printf is a function that take a undefined number of arguments. The problem is that those arguments are not typed.
When you specify int, double, ect... the compiler assign differente number of bytes (in a specific order) depending on the arguments. So when you call a function that has type argument, the function know how it should read those bytes. Here it cannot know since it isn't type. So the printf function is going to believe what you give it. If you ask for example for a 4 bytes when you real value is 8 bytes, the function will read the first 4 bytes believing it the value you ask for. But then the next value you try to match will start with the next 4 bytes. Wich will give you garbage.
You can try to do 2 printf, and you will see that the value of i is actually the good one. Only the way to read it was wrong.
int sum_element(float ele[], unsigned int len){
int sum=0.0; //mistake,should be : float sum = 0.0
int i=0;
for(i=0;i<= len-1;i++){
printf("sum=%f\n",sum);
printf("i=%d\n",i);
}
return sum;
}
Hope this can help.
EDIT:
Maybe a example is easier to understand. Try this function:
int sum_element(float ele[], unsigned int len){
int sum=24222.55455555; //mistake,should be : float sum = 0.0
char c = 0 ;
for(i=0;i<= len-1;i++){
printf("sum=%f, n= %d n2 = %d\n",sum,i,c);
}
return sum;
}
You should get a interesting value for n2.
Upvotes: 1
Reputation: 6834
I think the answer is that in the first case, the value being printed is not that of i
at all. Two parameters are passed to printf
which then reads two off. Those passed in are two int
s, and then a double
and and int
are read off. Because the double
is read off the stack first, when the int
is read it is not from where the value of i
was passed, hence the bogus value. Most likely the double
covers enough of the stack to include both the passed int
s.
Of course, results may vary, being undefined.
Upvotes: 0
Reputation: 215557
Nothing to see. You invoked undefined behavior by passing the wrong type to printf
, so all output of the program is meaningless. The %f
format specifier requires an argument of type double
(by the way, float
would automatically promote to double
in this context, so float
would be okay too), but you passed it an argument of type int
.
Upvotes: 6