0
#include<stdio.h>
int main(){
 int ret = 0;
 ret = func(1.0,2.0);
 printf("\n ret : %d \n",ret);
 return 0;
}
func(int a,int b){
 float m = 5.0;
 float n = 6.0;
 int sum = m + n;
 printf("\n sum : %d \n",sum);
 return a+b;
}

EDITED

sum : 11

ret : -877505847

why the float value passed to the integer throws a garbage value while the float value added and assigned to an integer inside the function gives the correct value 11 ?

Angus
  • 12,133
  • 29
  • 96
  • 151
  • What is the garbage value you're receiving? It looks like you should be returning 3, but what is being returned? – Sean Cogan Jun 06 '13 at 12:28
  • Can you provide the "garbage" value? I'm sure it would help diagnose – Scott Jones Jun 06 '13 at 12:28
  • 1
    Why would you ignore the warning, especially when a reputable source tells you that it's the source of your problem? That's why you're getting downvoted. At least try the suggestion... – Sean Cogan Jun 06 '13 at 12:51
  • @Angus I've updated my answer to explain why you're getting the wrong result. Basically, it comes back to needing to provide a declaration for `func`. – simonc Jun 06 '13 at 12:55
  • @Sean Cogan : Sorry , I missed to fix the warning and i was more concerned about the o/p . After fixing the warning , it works good. – Angus Jun 06 '13 at 13:09
  • I wasn't the one who suggested it, it was simonc. Give him the credit. – Sean Cogan Jun 06 '13 at 13:11
  • Sure. But my doubt isn't clarified yet. Please see my comment. – Angus Jun 06 '13 at 13:13

1 Answers1

6

You need to provide a declaration for func before calling it

int func(int a,int b);
int main() {
}
int func(int a,int b) {
    // implementation
}

Your code presumably compiled with a warning something like warning: implicit declaration of function 'func'. If you'd fixed this warning, you'd also have fixed the error.

It'd be good practice to have the compiler warn you about as many potential problems as possible. You may also want to guard against the possibility of missing warnings by treating them as errors. You can do this by adding -Wall -Werror to your build command for gcc or /W4 /Wx for MSVC.

Note that the correct value is returned if you pass ints into func. At a guess, this may be because the calling code doesn't know that it needs to cast the arguments to int and passes float instead. func then either reads registers/stack locations that floats weren't copied to or receives the bit representations of float arguments and treats them as int. Either of these will result in incorrect values of a, b being received. You can check this yourself by adding a printf inside func to note the values of its arguments.

simonc
  • 41,632
  • 12
  • 85
  • 103
  • 1
    Wouldn't it not even compile without the prototype? – Sean Cogan Jun 06 '13 at 12:29
  • 1
    @SeanCogan It will compile, but with a warning. Fixing the warning would have fixed the OP's error – simonc Jun 06 '13 at 12:29
  • I guess we've used different compilers, then. I used gcc to compile C when I wrote in C, and unless I'm mistaken it wouldn't compile if I didn't have the prototype for my function. – Sean Cogan Jun 06 '13 at 12:30
  • It does compile under gcc. Since it generates a warning, if you normally use `-Werror`, your warning would have been treated as an error – simonc Jun 06 '13 at 12:32
  • It will compile with the warning implicit declaration of the function – Angus Jun 06 '13 at 12:32
  • It will make the default return type as int. As long as we havent defined the function with any other return type other than int, the program holds good – Angus Jun 06 '13 at 12:32
  • Ok, never mind then. It's been quite a while since I've written in C, and I usually wouldn't run my programs if they had warnings anyway. – Sean Cogan Jun 06 '13 at 12:33
  • @simonac : It works fine after fixing the warning. But my doubt is , When passed func(1,2) , it didnt show any garbage value and gave me the correct answer. when i tried to pass func(1.0,2.0) it gave me the garbage value. why did it work when passed integers as parameters. – Angus Jun 06 '13 at 13:12
  • @Angus Does the last paragraph of my answer cover this for you? Presumably the caller and callee agreed on how to pass `int` arguments so we get lucky and the code works. If you pass `float`, the caller doesn't know that the args need to be cast as `int` and the callee doesn't know it hasn't been passed `int` arguments. In this case, the callee goes ahead and interprets the start of a `float` (or an uninitialised part of memory) as an `int`. – simonc Jun 06 '13 at 13:19
  • @simonc : I put the printf and got the values of the parameters a and b as 1 and 2. – Angus Jun 06 '13 at 13:24
  • 1
    With which compiler? That's not what I get with either gcc or msvc. Have you remembered to remove any forward declaration of `func` before testing this? – simonc Jun 06 '13 at 13:34
  • @simonc : you are right . I forget remove the forward declaration, i made in the program. I checked by removing it and got a garbage value for b. – Angus Jun 06 '13 at 13:38
  • Thanks for helping me understand, though i made mistakes :) – Angus Jun 06 '13 at 13:39
  • 1
    You're welcome. Everyone starts out by making mistakes. The best thing you could learn from this thread is that fixing all compiler warnings can be a nice quick way of fixing some hard to diagnose bugs :-) – simonc Jun 06 '13 at 13:42
  • The reason why func (1, 2) didn't give garbage is that the compiler guessed what the types are - since you passed two ints, it guessed that the parameters are int and was right. When you call func (1.0, 2.0) you pass two doubles, so the compiler guesses the parameters are double, and that guess is wrong. – gnasher729 Mar 25 '14 at 17:31