有时候,我们使用了数学函数,确不用链接-lm,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | $ cat test.c #include <math.h> #include <stdio.h> int main() { printf("%lf\n", log(2)); } $ cc test.c $ ./a.out 0.693147 $ ldd a.out linux-vdso.so.1 (0x00007fff9d19a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb057d80000) /lib64/ld-linux-x86-64.so.2 (0x00007fb057f8a000) $ readelf --dyn-syms a.out Symbol table '.dynsym' contains 7 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2) 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2) 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2) |
可以看到,ldd既没有要求libm.so,动态符号,也没有log。其实是gcc使用了内置的log函数。使用-fno-builtin,可以阻止gcc使用内置函数,此时编译将报错:
$ cc -fno-builtin test.c
/usr/bin/ld: /tmp/ccTICOvL.o: in function `main':
test.c:(.text+0x15): undefined reference to `log'
collect2: error: ld returned 1 exit status
参考
https://stackoverflow.com/questions/1033898/why-do-you-have-to-link-the-math-library-in-c
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html