Discussion:
pow function w/o math.h
(too old to reply)
zagreb
2009-09-17 08:44:01 UTC
Permalink
This program:
#include <stdio.h>
/*#include <math.h>*/
main() {
int a=4;
a=pow(a,4) ;
printf("%d\n", a);
}

Prints wired result. Also you can write:
a=pow(4,1,1,2,3,4,5,6,7,8,9);

What exactly is this code calling? It is not standard pow function in
math library.
Ulrich Eckhardt
2009-09-17 09:16:14 UTC
Permalink
Post by zagreb
#include <stdio.h>
/*#include <math.h>*/
main() {
int a=4;
a=pow(a,4) ;
printf("%d\n", a);
}
You are using pow() without a declaration in sight. This tells the compiler
to just guess the declaration. In this case, it will assume "int pow(int,
int);". Note that the return-type is always 'int', it is not determined
from the assignment.
Post by zagreb
a=pow(4,1,1,2,3,4,5,6,7,8,9);
What exactly is this code calling? It is not standard pow function in
math library.
Yes it is. However, that function takes two double values and returns a
double. Now imagine being passed some bytes that actually are an int but
interpreting them as if they were a double.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
zagreb
2009-09-17 10:38:45 UTC
Permalink
Post by Ulrich Eckhardt
Post by zagreb
#include <stdio.h>
/*#include <math.h>*/
main() {
int a=4;
a=pow(a,4) ;
printf("%d\n", a);
}
You are using pow() without a declaration in sight. This tells the compiler
to just guess the declaration. In this case, it will assume "int pow(int,
int);". Note that the return-type is always 'int', it is not determined
from the assignment.
Post by zagreb
a=pow(4,1,1,2,3,4,5,6,7,8,9);
What exactly is this code calling? It is not standard pow function in
math library.
Yes it is. However, that function takes two double values and returns a
double. Now imagine being passed some bytes that actually are an int but
interpreting them as if they were a double.
Uli
--
C++ FAQ:http://parashift.com/c++-faq-lite
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
I understand that (about prototype). But why is vc linking math
library without
my request (this can not be compiled without linker command on cc
platform).

I tried to debug both cases (w and w/o math.h) and with math.c vc
shows
exact lib where code for pow is, and w/o math.h I can't see stack
(i.e.
I can't see where is pow function).
Regards
Ulrich Eckhardt
2009-09-17 11:22:32 UTC
Permalink
Post by zagreb
I understand that (about prototype).
So why did you even mention that you are receiving strange results?
Post by zagreb
But why is vc linking math library without my request (this can
not be compiled without linker command on cc platform).
This is part of the standard C API, so why shouldn't it? Note that a
separate math library is a relict from some old platforms. A modern GCC
doesn't require any additional libs. Actually, concerning VC, I believe you
can tell the compiler/linker to not link the C runtime, but by default it
will be linked.
Post by zagreb
I tried to debug both cases (w and w/o math.h) and with math.c vc
shows exact lib where code for pow is, and w/o math.h I can't see
stack (i.e.I can't see where is pow function).
Well, you broke it and now it doesn't work. I guess that the stack is just
not set up for the debugger to digest. In particular there is a thing
called frame-pointer which might get clobbered by your abuse.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
zagreb
2009-09-17 12:59:10 UTC
Permalink
Post by Ulrich Eckhardt
Post by zagreb
I understand that (about prototype).
So why did you even mention that you are receiving strange results?
Post by zagreb
But why is vc linking math library without my request (this can
not be compiled without linker command on cc platform).
This is part of the standard C API, so why shouldn't it? Note that a
separate math library is a relict from some old platforms. A modern GCC
doesn't require any additional libs. Actually, concerning VC, I believe you
can tell the compiler/linker to not link the C runtime, but by default it
will be linked.
Post by zagreb
I tried to debug both cases (w and w/o math.h) and with math.c vc
shows exact lib where code for pow is, and w/o math.h I can't see
stack (i.e.I can't see where is pow function).
Well, you broke it and now it doesn't work. I guess that the stack is just
not set up for the debugger to digest. In particular there is a thing
called frame-pointer which might get clobbered by your abuse.
Uli
--
C++ FAQ:http://parashift.com/c++-faq-lite
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Please excuse my ignorance and define "modern GCC"
TIA
Ulrich Eckhardt
2009-09-17 13:19:31 UTC
Permalink
Post by zagreb
define "modern GCC"
GCC is the GNU Compiler Collection. With modern, I mean anything since
version 4 (though version 3 is also not completely out-of-date). I tested
my code with version 4.2 for Linux/x86.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
zagreb
2009-09-17 13:33:29 UTC
Permalink
Post by Ulrich Eckhardt
GCC is the GNU Compiler Collection. With modern, I mean anything since
version 4 (though version 3 is also not completely out-of-date). I tested
my code with version 4.2 for Linux/x86.
Ok here's code:

***@linux:~/tmp$ uname -a
Linux linux 2.6.28-15-generic #49-Ubuntu SMP Tue Aug 18 18:40:08 UTC
2009 i686 GNU/Linux
***@linux:~/tmp$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/
README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/
usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-
included-gettext --enable-threads=posix --enable-nls --with-gxx-
include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-
clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --
enable-targets=all --with-tune=generic --enable-checking=release --
build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
***@linux:~/tmp$ cat pow1.c
#include <stdio.h>
#include <math.h>

int
main(void)
{

printf("%f\n", pow(2,3));
return 0;
}

***@linux:~/tmp$ gcc -o pow1 pow1.c
***@linux:~/tmp$ ./pow1
8.000000
***@linux:~/tmp$ cat pow3.c
#include <stdio.h>
#include <math.h>

int
main(void)
{
int x;
int y = 3;

for (x=2; x<11; x++)
printf("%f\n", pow(x,y));
return 0;
}

***@linux:~/tmp$ gcc -o pow3 pow3.c
/tmp/cciCYuL1.o: In function `main':
pow3.c:(.text+0x31): undefined reference to `pow'
collect2: ld returned 1 exit status
***@linux:~/tmp$ gcc -o pow3 pow3.c -lm
***@linux:~/tmp$ ./pow3
8.000000
27.000000
64.000000
125.000000
216.000000
343.000000
512.000000
729.000000
1000.000000
***@linux:~/tmp$


It is rather "modern GCC" since it is 4.3.3
Anyhow, it does not compile pow3.c program without math library linked
explicitly.
Program pow1.c is succesfully compiled because in fact it _does_not_
call pow at all.
Regards
Ulrich Eckhardt
2009-09-18 08:21:24 UTC
Permalink
Post by zagreb
printf("%f\n", pow(2,3));
[..works..]
Post by zagreb
for (x=2; x<11; x++)
printf("%f\n", pow(x,y));
[..fails without -lm..]
Post by zagreb
Program pow1.c is succesfully compiled because in fact it _does_not_
call pow at all.
Interesting. I guess the compiler knows about pow and computes the value at
compile time, making any math libraries unnecessary, but I'm speculating
there.

Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
zagreb
2009-09-18 09:37:28 UTC
Permalink
Post by Ulrich Eckhardt
        for (x=2; x<11; x++)
        printf("%f\n", pow(x,y));
[..fails without -lm..]
Exactly - gcc does not link math lib "per se"
Post by Ulrich Eckhardt
printf("%f\n", pow(2,3));
[..works..]
Interesting. I guess the compiler knows about pow and computes the value at
compile time, making any math libraries unnecessary, but I'm speculating
there.
Try to compile it in assembly code - you'll see that it just prints
value:
.long 1090519040
(which is in fact floating point representation of number 8)
Regards

Continue reading on narkive:
Loading...