Date: Wed, 12 Apr 2006 14:05:46 +0300 From: Giorgos Keramidas <keramida@ceid.upatras.gr> To: Jonathan Herriott <herriojr@gmail.com> Cc: freebsd-questions@freebsd.org Subject: Re: pow function working unexpectedly Message-ID: <20060412110546.GB34707@gothmog.pc> In-Reply-To: <6a56d69c0604111554o587ce2c5ha1ff4ea20bbab0a4@mail.gmail.com> References: <6a56d69c0604111554o587ce2c5ha1ff4ea20bbab0a4@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2006-04-11 22:54, Jonathan Herriott <herriojr@gmail.com> wrote: > I just want to make sure I'm not being stupid before I send in a bug. > The problem seems to be with gcc when using the pow function in the > math.h library. Here's code that works: > > #include <stdio.h> > #include <math.h> > > int main() > { > printf("%f\n", pow(2,3)); > return 0; > } > > > Now, the following will not compile: > > #include <stdio.h> > #include <math.h> > > int main() > { > int x = 2; // I tried these as doubles too since the pow function > takes doubles > int y = 3; > > printf("%f\n", pow(x,y)); > return 0; > } > > I compiled both programs using: > gcc test.c > > The second example gives the following error: > /var/tmp//ccxtkMwv.o(.text+0x45): In function `main': > : undefined reference to `pow' There are two things at work here that are a bit confusing. In the first case, the arguments of pow() are constants, so the compiler knows the result of the pow() call at compile-time. GCC tries to optimize this call away by replacing the entire pow() call with the literal result. You can see this by: # $ cat -n pow1.c # 1 #include <stdio.h> # 2 #include <math.h> # 3 # 4 int # 5 main(void) # 6 { # 7 # 8 printf("%f\n", pow(2,3)); # 9 return 0; # 10 } If you compile this program to assembler, there is no call to pow(): # $ gcc -std=c99 -pedantic -O2 -S pow1.c # $ cat -n pow1.s # 1 .file "pow1.c" # 2 .section .rodata.str1.1,"aMS",@progbits,1 # 3 .LC1: # 4 .string "%f\n" # 5 .text # 6 .p2align 2,,3 # 7 .globl main # 8 .type main, @function # 9 main: # 10 pushl %ebp # 11 movl %esp, %ebp # 12 subl $8, %esp # 13 andl $-16, %esp # 14 subl $20, %esp # 15 pushl $1075838976 # 16 pushl $0 # 17 pushl $.LC1 # 18 call printf # 19 xorl %eax, %eax # 20 leave # 21 ret # 22 .size main, .-main # 23 .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518" # $ Lines 15-17 are pushing the arguments of printf() on the stack, so obviously GCC has pre-calculated the value of pow(2,3) for us. With the second program, which uses variables for storing the values passed to pow(), GCC cannot use the same trick, as the *values* of the variables are only known at runtime. This way, this program: # $ cat -n pow2.c # 1 #include <stdio.h> # 2 #include <math.h> # 3 # 4 int # 5 main(void) # 6 { # 7 int x = 2; /* I tried these as doubles too since the pow function takes doubles */ # 8 int y = 3; # 9 # 10 printf("%f\n", pow(x,y)); # 11 return 0; # 12 } # $ Compiles to slightly different object code: # $ gcc -std=c99 -pedantic -O2 -S pow2.c # $ cat -n pow2.s # 1 .file "pow2.c" # 2 .section .rodata.str1.1,"aMS",@progbits,1 # 3 .LC0: # 4 .string "%f\n" # 5 .text # 6 .p2align 2,,3 # 7 .globl main # 8 .type main, @function # 9 main: # 10 pushl %ebp # 11 movl %esp, %ebp # 12 subl $8, %esp # 13 andl $-16, %esp # 14 subl $32, %esp # 15 pushl $1074266112 # 16 pushl $0 # 17 pushl $1073741824 # 18 pushl $0 # 19 call pow # 20 addl $20, %esp # 21 fstpl (%esp) # 22 pushl $.LC0 # 23 call printf # 24 xorl %eax, %eax # 25 leave # 26 ret # 27 .size main, .-main # 28 .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518" Here a call to pow() is used, so the second program uncovers the fact that you need the -lm math library to work with math functions, which is why GCC complains about an undefined reference to pow(). > If I comile with g++, I have no issues. Are these results that I > should have? If so, why? If not, I'm going to submit the bug on gcc > (or the linker, but I'm guessing it's the same group). This is not a C++ program, so you should use a C compiler for it :) Regards, Giorgos
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060412110546.GB34707>