I am compiling the following code :
#include <stdio.h>
#include <math.h>
main() {
int x=2, y=3;
pow(2,3);
pow(x,y);
}
If I compile this as "gcc file.c" (ie, I am NOT linking with libm.a), the first call to 'pow' does not generate a linker error. Only the secong call to the 'pow' function generates the expected undefined reference to pow - linker error.
I want to know how is the first call getting resolved
You could disassemble you program in gdb
to be sure. This is what happens on my machine (cygwin 32, gcc):
This program:
#include <stdio.h>
#include <math.h>
int main() {
int x = 2, y = 3;
pow(x, y);
return 0;
}
Generates this code (Notice the call to pow
in there):
(gdb) break main
Breakpoint 1 at 0x4011ae: file test.c, line 6.
(gdb) run
...
Breakpoint 1, main () at test.c:6
6 int x = 2, y = 3;
(gdb) disas
Dump of assembler code for function main:
0x004011a0 <+0>: push %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: sub $0x20,%esp
0x004011a9 <+9>: call 0x401250 <__main>
=> 0x004011ae <+14>: movl $0x2,0x1c(%esp)
0x004011b6 <+22>: movl $0x3,0x18(%esp)
0x004011be <+30>: fildl 0x18(%esp)
0x004011c2 <+34>: fildl 0x1c(%esp)
0x004011c6 <+38>: fxch %st(1)
0x004011c8 <+40>: fstpl 0x8(%esp)
0x004011cc <+44>: fstpl (%esp)
0x004011cf <+47>: call 0x401258 <pow>
0x004011d4 <+52>: fstp %st(0)
0x004011d6 <+54>: mov $0x0,%eax
0x004011db <+59>: leave
0x004011dc <+60>: ret
End of assembler dump.
But if I only have this one:
#include <stdio.h>
#include <math.h>
int main() {
pow(2, 3);
return 0;
}
All I get is:
Dump of assembler code for function main:
0x004011a0 <+0>: push %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: call 0x401230 <__main>
=> 0x004011ab <+11>: mov $0x0,%eax
0x004011b0 <+16>: leave
0x004011b1 <+17>: ret
Showing pretty clearly your call to pow
was removed probably due to some dead code optimization. You're not using the return value and you're calling it for constant values - I guess the compiler considered safe to just get rid of it.
Now considering I actually use pow-s return value:
#include <stdio.h>
#include <math.h>
int main() {
printf("%lf\n", pow(2,3));
return 0;
}
I get this:
0x004011a0 <+0>: push %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: sub $0x10,%esp
0x004011a9 <+9>: call 0x401240 <__main>
0x004011ae <+14>: fldl 0x403068
0x004011b4 <+20>: fstpl 0x4(%esp)
0x004011b8 <+24>: movl $0x403060,(%esp)
0x004011bf <+31>: call 0x401248 <printf>
=> 0x004011c4 <+36>: mov $0x0,%eax
0x004011c9 <+41>: leave
0x004011ca <+42>: ret
Still no call to pow
.
And printing the value on the stack that gets sent to printf
:
(gdb) x /1f $esp+4
0x22abf4: 8
You can also take a look at this: https://gcc.gnu.org/gcc-4.3/changes.html#mpfropts .
C预编译器意识到这个表达式是一个常量,并且在不使用math.h的情况下将其解析为常量(不调用pow()函数)。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.