### Thread: Function turns my ints into garbage ??

1. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2013
Posts
109
Rep Power
3

#### Function turns my ints into garbage ??

I have an exercise: "The country A has 50M inhabitants, and its population grows 3% per year. The country B, 70M and grows 2% per year. Tell in how many years A will surpass B."

I wrote a recursive function that recieves 50.0 and 70.0 as floats, multiplies untill A>B, and returns the number of years.

Inside the function, num_years prints correctly. When i try to use the return value i get a very large int (why??)

Code:
#include<stdio.h>

int pop_count(float pop1, float pop2)
{
static int num_years=0;

if(pop1 > pop2)
return num_years;

++num_years;
pop_count((pop1)*=(1.03), (pop2)*=(1.02));
}

int main(void)
{
int ret=pop_count(50.0, 70.0);

getch();
return 0;
}
Also when i test-print pop1 and pop2 it shows that pop1=0 for the first 3 rounds (!!) and afterwards both pop2 and pop1 receive very large values.

I just can't see the mistake- can anybody see it ?? :confused:
Last edited by C learner; August 30th, 2013 at 09:07 PM.
2. The very last call in the stack will return num_years, but what about the calls happening before it? What will they return?

And any reason why a static variable and not a loop? You could even jump right to the solution with a bit of math instead.

 With some printf()s I get output
Code:
50.000, 70.000
51.500, 71.400
53.045, 72.828
54.636, 74.285
56.275, 75.770
57.964, 77.286
59.703, 78.831
61.494, 80.408
63.339, 82.016
65.239, 83.656
67.196, 85.330
69.212, 87.036
71.288, 88.777
73.427, 90.552
75.629, 92.364
77.898, 94.211
80.235, 96.095
82.642, 98.017
85.122, 99.977
87.675, 101.977
90.306, 104.016
93.015, 106.097
95.805, 108.219
98.679, 110.383
101.640, 112.591
104.689, 114.842
107.830, 117.139
111.064, 119.482
114.396, 121.872
117.828, 124.309
121.363, 126.795
125.004, 129.331
128.754, 131.918
132.617, 134.556
136.595, 137.247
140.693, 139.992
Stopped after 35 iterations
Code:
\$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
\$
Last edited by requinix; August 30th, 2013 at 09:27 PM.
3. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2013
Posts
109
Rep Power
3
>>No, the exercise was to do it using C not math :P

Oops, accidentally wrote %d instead of %f >_<

Still, why does my compiler make ret a large int, whereas an online compiler got it all right ??
Last edited by C learner; August 30th, 2013 at 09:56 PM.
4. > Still, why does my compiler make ret a large int, whereas an online compiler got it all right ??

> requinix The very last call in the stack will return num_years, but what about the calls happening before it? What will they return?

Also, getting two different results from two different compilers is a sign your code is broken in some way. In the large domain of undefined behaviour, all sorts of things can happen (including producing the right answer despite your best efforts to make a mess of it).

Turn up the warning level on your compiler.
Code:
\$ gcc -Wall baz.c
baz.c: In function ‘main’:
baz.c:16:9: warning: unused variable ‘ret’ [-Wunused-variable]
baz.c: In function ‘pop_count’:
baz.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]

• dwise1_aol agrees : "If you lie to the compiler, it will get its revenge." [Henry Spencer]
Last edited by salem; August 31st, 2013 at 12:20 AM.
5. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2013
Posts
109
Rep Power
3
Ok, i just compiled my code in 5 (!) different online compilers and they all print the output the way it should work.

>> What do the other calls return: Why would the other calls return ANYTHING if pop1 > pop2 is false all the way untill the last call ?
Last edited by C learner; August 31st, 2013 at 06:45 AM.
6. Originally Posted by C learner
Ok, i just compiled my code in 5 (!) different online compilers and they all print the output the way it should work.
That's great but your code is still flawed.

Originally Posted by C learner
>> What do the other calls return: As soon as the recursion reaches its final depth, it starts going backwards, each time checking pop1>pop2 and returning the SAME num_years to the level above it= 35. That number doesn't change anymore, right ?
Your description is incorrect: the last call to pop_count will return, yes, but all the calls leading up to it don't. They only call pop_count without trying to return what it returned. Your code should have
Code:
return pop_count(pop1 * 1.03, pop2 * 1.02);
(which also does away with the useless assignments).

Originally Posted by C learner
Is there something wrong with my compiler ?
No, you're merely getting the right results from an incorrect input: just because it works in a few cases does not mean you're doing what you should do. -Wall, like salem demonstrated, will show you many potential problems with your code, and in this case it shows (1) the ret variable isn't used and (2) pop_count wasn't always returning. It just happens that the undefined behavior from not returning a value gave you the same result you were expecting.
7. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2013
Posts
109
Rep Power
3
Does it mean that the function will NOT pass the num_years backwards (to the previous calls) since the permission to do it is by having the return command for the name of the function ?

So basically num_years is passed just 1 level back, while it should be passed 35 levels back ?

Am i correct ?

-Sorry for my heavy editting.
Last edited by C learner; August 31st, 2013 at 07:01 AM.
8. Originally Posted by C learner
Does it mean that the function will NOT pass the num_years backwards (to the previous calls) since the permission to do it is by having the return command for the name of the function ?

So basically num_years is passed just 1 level back, while it should be passed 35 levels back ?

Am i correct ?
That's exactly it. There is no such "permission" thing: if you want the function to return the result of calling itself recursively then you have to write it as such in the code.
9. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Jul 2013
Posts
109
Rep Power
3
That's exactly what i missed, thank you very much :)

Now i fully understand recursion :cheers: