From owner-freebsd-questions@FreeBSD.ORG Wed Apr 12 11:05:10 2006 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F2F3B16A401 for ; Wed, 12 Apr 2006 11:05:09 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from igloo.linux.gr (igloo.linux.gr [62.1.205.36]) by mx1.FreeBSD.org (Postfix) with ESMTP id 139F143D45 for ; Wed, 12 Apr 2006 11:05:08 +0000 (GMT) (envelope-from keramida@ceid.upatras.gr) Received: from gothmog.pc (aris.bedc.ondsl.gr [62.103.39.226]) (authenticated bits=128) by igloo.linux.gr (8.13.6/8.13.6/Debian-1) with ESMTP id k3CB4sdX007559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 12 Apr 2006 14:04:56 +0300 Received: from gothmog.pc (gothmog [127.0.0.1]) by gothmog.pc (8.13.6/8.13.6) with ESMTP id k3CB5k2a024453; Wed, 12 Apr 2006 14:05:46 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Received: (from giorgos@localhost) by gothmog.pc (8.13.6/8.13.6/Submit) id k3CB5kX4024450; Wed, 12 Apr 2006 14:05:46 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Date: Wed, 12 Apr 2006 14:05:46 +0300 From: Giorgos Keramidas To: Jonathan Herriott Message-ID: <20060412110546.GB34707@gothmog.pc> References: <6a56d69c0604111554o587ce2c5ha1ff4ea20bbab0a4@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <6a56d69c0604111554o587ce2c5ha1ff4ea20bbab0a4@mail.gmail.com> X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (score=-3.48, required 5, autolearn=not spam, ALL_TRUSTED -1.80, AWL 0.92, BAYES_00 -2.60) X-Hellug-MailScanner-From: keramida@ceid.upatras.gr X-Spam-Status: No Cc: freebsd-questions@freebsd.org Subject: Re: pow function working unexpectedly X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Apr 2006 11:05:10 -0000 On 2006-04-11 22:54, Jonathan Herriott 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 > #include > > int main() > { > printf("%f\n", pow(2,3)); > return 0; > } > > > Now, the following will not compile: > > #include > #include > > 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 # 2 #include # 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 # 2 #include # 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