undefined reference to `pow'
undefined reference to `sqrt'
undefined reference to `sin'
undefined reference to `cos'
undefined reference to `exp'
数学函数 sin、cos、exp、sqrt、pow 等是 C 标准函数库的一部分,但它们被独立存储在数学函数库 libm 中。GCC 在编译链接程序时,是不会自动链接该库的。需要手工修改配置让 Eclipse 在调用 GCC 编译链接程序时,将 libm 加入到链接的文件列表中。
/*
============================================================================
Name : atof_example_1.c
Author : Foreverstrong Cheng
Version :
Copyright : Copyright 2019 ForeverStrong License
Description : Hello World in C, Ansi-style
============================================================================
*/
/* atof example: sine calculator */
#include /* printf, fgets */
#include /* atof */
#include /* sin */
int main()
{
double n, m;
double pi = 3.1415926535;
char buffer[256];
printf("Enter degrees: ");
fgets(buffer, 256, stdin);
n = atof(buffer);
m = sin(n * pi / 180);
printf("The sine of %f degrees is %f\n", n, m);
return 0;
}
13:36:53 **** Build of configuration Debug for project atof_example ****
make all
Building file: ../src/atof_example_1.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/atof_example_1.d" -MT"src/atof_example_1.o" -o "src/atof_example_1.o" "../src/atof_example_1.c"
Finished building: ../src/atof_example_1.c
Building target: atof_example
Invoking: GCC C Linker
gcc -o "atof_example" ./src/atof_example_1.o
./src/atof_example_1.o: In function `main':
/home/strong/eclipse-work/atof_example/Debug/../src/atof_example_1.c:25: undefined reference to `sin'
makefile:30: recipe for target 'atof_example' failed
collect2: error: ld returned 1 exit status
make: *** [atof_example] Error 1
13:36:54 Build Finished (took 317ms)
right mouse click on the desired project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> GCC C Linker -> Libraries -> Libraries (-l) -> Add… -> OK -> Apply and Close
添加的库是 libm.so,程序中包含 math.h。在链接时要链接到数学库,加上 -lm
编译选项。
使用 math.h 中声明的库函数有一点特殊之处,gcc 命令行必须加 -lm
选项。因为数学函数位于 libm.so 库文件中 (这些库文件通常位于 /lib
目录下),-lm
选项告诉编译器,程序中用到的数学函数要到这个库文件里找。大部分库函数 (例如 printf) 位于 libc.so 库文件中,使用 libc.so 中的库函数在编译时不需要加 -lc
选项,加了也不报错,这个选项是 gcc 的默认选项。
用 -L
选项定义指定的路径,不填写的话默认是 /lib
和 /usr/lib
内。因为 Linux 下所有的函数库都是以 lib 开头的。所以去除头和尾,那么 m 就是代表 libm.so (m 是库名,libm.so 是库文件名)。在使用 -l
参数时,通常的习惯是除去 lib 函数库头和后面的版本号,使用库名和参数 -l
连接,形成 -lm
。在 gcc 找不到库时,可是使用 -l
直接给定库名。(如果库不在默认路径的话,用 -L
选项可添加路径,gcc sin.c -lm -o sin
等价于 gcc sin.c -lm -L/lib -L/usr/lib -o sin
)。
13:48:22 **** Incremental Build of configuration Debug for project atof_example ****
make all
Building target: atof_example
Invoking: GCC C Linker
gcc -o "atof_example" ./src/atof_example_1.o -lm
Finished building target: atof_example
13:48:22 Build Finished (took 317ms)
Enter degrees: 45
The sine of 45.000000 degrees is 0.707107
C 标准主要由两部分组成,一部分描述 C 语法,另一部分描述 C 标准库。C 标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏定义。要在一个平台上支持 C 语言,不仅要实现 C 编译器,还要实现 C 标准库,这样的实现才算符合 C 标准。不符合 C 标准的实现也是存在的,例如部分单片机的 C 语言开发工具中只有 C 编译器而没有完整的 C 标准库。
在 Linux 平台上最广泛使用的 C 函数库是 glibc,其中包括 C 标准库的实现。几乎所有 C 程序都要调用 glibc 的库函数,所以 glibc 是 Linux 平台 C 程序运行的基础。glibc 提供一组头文件和一组库文件,最基本、最常用的 C 标准库函数和系统函数在 libc.so 库文件中,几乎所有 C 程序的运行都依赖于 libc.so。数学计算的 C 程序依赖于 libm.so,多线程的 C 程序依赖于 libpthread.so。libc 专指 libc.so 这个库文件,glibc 指的是 glibc 提供的所有库文件。
glibc 并不是 Linux 平台唯一的基础 C 函数库,也有人在开发别的 C 函数库,例如适用于嵌入式系统的 uClibc。
The GNU C Library (glibc) is the GNU Project’s implementation of the C standard library. Despite its name, it now also directly supports C++ (and, indirectly, other programming languages). It was started in the early 1990s by the Free Software Foundation (FSF) for their GNU operating system.
它由自由软件基金会 (FSF) 于 20 世纪 90 年代初开始用于他们的 GNU 操作系统。
In computing, uClibc (µClibc) is a small C standard library intended for Linux kernel-based operating systems for embedded systems and mobile devices. uClibc was created to support μClinux, a version of Linux not requiring a memory management unit and thus suited for microcontrollers (uCs; the “u” is a Latin script typographical approximation - not a proper romanization, which would be letter “m” - of μ for “micro”).
uClibc 是一个面向嵌入式 Linux 系统的小型的 C 标准库。最初 uClibc 是为了支持 uClinux 而开发,这是一个不需要内存管理单元的 Linux 版本,因此适合于微控制器系统 (uCs,此处 u 是代表 micro 的 μ 的罗马化)。
despite [dɪ'spaɪt]:prep. 即使,尽管 n. (诗/文) 侮辱,伤害,轻视,鄙视,憎恨 v. 故意使烦恼,故意伤害
indirectly [,ɪndɪ'rek(t)lɪ]:adv. 间接地,不诚实,迂回地
typographical[taɪpə'græfɪkl]:adj. 印刷上的,排字上的
approximation [ə,prɒksɪ'meɪʃn]:n. 近似法,接近,近似值
romanization [,romənə'zeʃən]:n. 古罗马化,皈依天主教,用罗马字体书写
[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/