woodslee
woodslee

Reputation: 61

a strange thing when test unsigned int value

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

Answers (3)

Marc Simon
Marc Simon

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

Keith
Keith

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 ints, 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 ints.

Of course, results may vary, being undefined.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

Related Questions