简体   繁体   English

与 gcc 和 -lm 的链接不会在 Ubuntu 上定义 ceil()

[英]Linking with gcc and -lm doesn't define ceil() on Ubuntu

I am currently using gcc to compile and I need to use <math.h> .我目前正在使用 gcc 进行编译,我需要使用<math.h> Problem is that it won't recognize the library.问题是它无法识别图书馆。 I have also tried -lm and nothing.我也试过-lm并没有。 The function I tried to use was ceil() and I get the following error:我尝试使用的函数是ceil()并且出现以下错误:

: undefined reference to `ceil'
collect2: ld returned 1 exit status

I am using the latest Ubuntu and math.h is there.我正在使用最新的 Ubuntu 并且 math.h 在那里。 I tried to use -lm in a different computer and it work perfectly.我尝试在另一台计算机上使用-lm并且它运行良好。

Does anyone know how to solve this problem?有谁知道如何解决这个问题?


I did include <math.h> .我确实包括了<math.h> Also, the command I used was:另外,我使用的命令是:

gcc -lm -o fb file.c

Take this code and put it in a file ceil.c :获取此代码并将其放入文件ceil.c

#include <math.h>
#include <stdio.h>
int main(void)
{
    printf("%f\n", ceil(1.2));
    return 0;
}

Compile it with:编译它:

$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm

One of those two should work.这两个中的一个应该可以工作。 If neither works, show the complete error message for each compilation.如果两者都不起作用,则显示每个编译的完整错误消息。 Note that -lm appears after the name of the source file (or the object file if you compile the source to object before linking).请注意, -lm出现在源文件(或目标文件,如果在链接之前将源编译为目标文件)的名称之后。

Notes:笔记:

  1. A modern compiler might well optimize the code to pass 2.0 directly to printf() without calling ceil() at all at runtime, so there'd be no need for the maths library at all.现代编译器可能会优化代码以将 2.0 直接传递给printf()而在运行时根本不调用ceil() ,因此根本不需要数学库。

  2. Rule of Thumb: list object files and source files on the command line before the libraries.经验法则:在库之前在命令行上列出目标文件和源文件。 This answer shows that in use: the -lm comes after the source file ceil.c .这个答案表明在使用中: -lm出现在源文件ceil.c If you're building with make etc, then you typically use ceil.o on the command line (along with other object files);如果您使用make等构建,那么您通常在命令行上使用ceil.o (以及其他目标文件); normally, you should list all the object files before any of the libraries.通常,您应该在任何库之前列出所有目标文件。

There are occasionally exceptions to the rule of thumb, but they are rare and would be documented for the particular cases where the exception is expected/required.经验法则偶尔会有例外,但它们很少见,并且会针对预期/需要例外的特定情况进行记录。 In the absence of explicit documentation to the contrary, apply the rule of thumb.如果没有相反的明确文件,请应用经验法则。

Just wanted to mention that Peter van der Linden's book Expert C Programming has a good treatment on this subject in chapter 5 Thinking of Linking .只是想提一下 Peter van der Linden 的书Expert C Programming在第 5 章Thinking of Linking 中对这个主题有很好的处理。

Archives (static libraries) are acted upon differently than are shared objects (dynamic libraries).档案(静态库)的作用不同于共享对象(动态库)。 With dynamic libraries, all the library symbols go into the virtual address space of the output file, and all the symbols are available to all the other files in the link.对于动态库,所有库符号都进入输出文件的虚拟地址空间,并且所有符号都可用于链接中的所有其他文件。 In contrast, static linking only looks through the archive for the undefined symbols presently known to the loader at the time the archive is processed.相比之下,静态链接只在档案中查找加载器在处理档案时当前已知的未定义符号。

If you specify the math library (which is usually a static one) before your object files, then the linker won't add any symbols.如果您在目标文件之前指定数学库(通常是静态库),则链接器将不会添加任何符号。

Try compiling like that:尝试这样编译:

gcc -Wall -g file.c -lm -o file

I had the same problem and it was solved using this command.我遇到了同样的问题,使用此命令解决了。 Also if you installed your Ubuntu the same day you had the problem it might be an update problem.此外,如果您在遇到问题的同一天安装了 Ubuntu,则可能是更新问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM