相关疑难解决方法(0)

为什么必须在C中链接数学库?

如果我包含<stdlib.h><stdio.h>在C程序中,我不必在编译时链接这些,但我必须链接到<math.h>,使用-lmgcc,例如:

gcc test.c -o test -lm
Run Code Online (Sandbox Code Playgroud)

这是什么原因?为什么我必须显式链接数学库而不是其他库?

c compilation math.h

241
推荐指数
7
解决办法
11万
查看次数

gcc:为什么链接数学库需要-lm标志?

我刚刚发现-lmgcc需要这个标志,以便编译一个从数学库中引用函数的程序.我想知道为什么在编译包含其他库(如时间库)的程序时不需要显式链接标志.如果我编写一个time()调用该函数的程序,即使没有链接选项也可以编译没有任何问题.但是如果没有-lm旗帜,那么涉及数学库的程序将无法运行.

任何人都可以解释这种行为背后的原因吗?谢谢你的时间.

gcc libc

62
推荐指数
0
解决办法
4万
查看次数

log(10.0)可以编译但是log(0.0)不能吗?

对于以下C源代码:

#include <math.h>

int main(void)
{
    double          x;

    x = log(0.0);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译时gcc -lm,我得到:

/tmp/ccxxANVH.o: In function `main':
a.c:(.text+0xd): undefined reference to `log'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

但是,如果我替换log(0.0)log(10.0),那么它可以成功编译.

我不太明白这一点,因为无论它们是否具有数学意义,它们都应该编译 - 没有语法错误.有人能解释一下吗?

以防万一,我的gcc -v输出:

Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 …
Run Code Online (Sandbox Code Playgroud)

c gcc math.h constantfolding

46
推荐指数
2
解决办法
2714
查看次数

为什么需要显式的`-lm`编译器选项

可能重复:
gcc:为什么链接数学库需要-lm标志?

一般来说,除了包含头文件之外,为了使用任何数学函数,math.h您必须使用链接器选项-lm进行链接.-l这里将指代用于搜索特定库的链接器选项libm.o.

我的问题是

为什么GCC默认不包含此库?是因为库大量使用数学协处理器,它需要添加额外的代码来初始化浮点初始化(我可能在这里使用错误的术语)?

注意

我刚刚查看了链接http://stackoverflow.com中提到的所有答案.这对我来说没什么意义.归因于三个基本原因

  1. 保证标准库可用.链接其他posix库(如pthread)显然是有意义的,但为什么我们必须为标准库做一个显式链接.即使是历史原因也不是很清楚.
  2. 为什么libm与libc分开?
  3. 为什么我们仍然在最近的gcc编译器中继承这些行为?它有什么简单性?这是我测试的,没有libm和libm.没有libm的那个,我写了我自己的Pow版本

这是一个例子

abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c "echo {} && echo "-----------------" && cat {}"
Test_withlibm.c
-----------------
#include<stdio.h>
#include<math.h>
int main() {
    int i=20;
    double output1=pow(2.618033988749895,i);
    return 0;
    }
Test_withoutlibm.c
-----------------
#include<stdio.h>
#include<math.h>
double Pow(double _X, int _Y)  {
    double _Z = 1;
    for (; _Y; _X *= _X) {
    if (_Y & 1) _Z *= _X;
    _Y >>= 1;
    } …
Run Code Online (Sandbox Code Playgroud)

c floating-point gcc

10
推荐指数
1
解决办法
9933
查看次数

sqrt()函数不使用变量参数

我不知道我是否遗漏了一些明显的东西,但似乎我无法计算C中变量的平方根; sqrt()函数似乎只适用于常量.这是我的代码:

#include <math.h>
#include <stdio.h>

int main()
{
    double a = 2.0;
    double b = sqrt(a);
    printf("%f", b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此程序时,我收到以下错误:

gcc -Wall -o "test2" "test2.c" (in directory: /home/eddy/Code/euler)
/tmp/ccVfxkNh.o: In function `main':
test2.c:(.text+0x30): undefined reference to `sqrt'
collect2: ld returned 1 exit status
Compilation failed.
Run Code Online (Sandbox Code Playgroud)

但是,如果我将sqrt()中的参数替换为常量(例如2.0,(b = sqrt(2.0))),那么它可以正常工作.sqrt()不应该使用变量或其他东西吗?

谢谢您的帮助

c compiler-errors math.h sqrt

9
推荐指数
1
解决办法
1万
查看次数

在编译和链接C代码时,为什么在某些情况下不需要-lm?

我这里有一个示例文件:

#include <stdio.h>
#include <math.h>

int main(){
  printf("%f\n", log(10));
}
Run Code Online (Sandbox Code Playgroud)

当我用gcc sample.c -o a它编译它时工作得很好.我可以运行它./a并产生2.302585预期的输出.

然而,当我的文件看起来像这样:

#include <stdio.h>
#include <math.h>

int main(){
  double a = 10;
  printf("%f\n", log(a));
}
Run Code Online (Sandbox Code Playgroud)

它没有编译gcc sample.c -o a.相反,我必须使用,gcc sample.c -o a -lm以便我可以明显地告诉它"链接数学"...这是我没有真正遵循的地方,为什么我不必在第一个例子中链接数学?它究竟是什么意思必须"链接数学"?自从我使用C编译器以来已经有一段时间了,所以如果这是一个糟糕的问题,请原谅我.

c macros gcc math.h compiler-optimization

9
推荐指数
2
解决办法
270
查看次数

是否允许全局静态标识符以单个_开头?

换句话说,静态(=文件范围)全局变量可以从一个下划线开始,而不会产生C实现的名称冲突的可能性吗?

https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html 表示"...保留名称包括以下划线开头的所有外部标识符(全局函数和变量)('_' )......(强调我的).

我注意到Linux内核启动的功能可能不应该直接用双下划线调用.

我发现这个概念很有用,而且我发现它比识别"私有"标识符_(_)something更容易阅读something_,但我理解(?)双下划线邀请名称与C实现冲突.

全球性,静态性 _variables_functions安全性?

c

9
推荐指数
1
解决办法
93
查看次数

需要在clang中使用-lm和pow(),但不能在sqrt()中使用

在FreeBSD上10.1使用Clang版本3.4.1

现在我已经看到其他线程询问如何使用pow()进行编译,但我还没有看到有这个问题的线程.举个例子:

#include <math.h>
#include <stdio.h>

int main()
{
  float result;
  result = pow(2,3);
  printf("%d", result);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在使用pow(),我需要发出clang参数-lm.

cc -lm -o name name.c

但是,更换pow(2,3)sqrt(5);,我可以编译cc -o name name.c.如果它们都使用math.h,那么为什么pow()需要链接到库?方面没有:安装gcc进行测试,我根本不需要使用-lm.

c clang

4
推荐指数
1
解决办法
639
查看次数