c - 在 gcc 中使用数学函数时出错?

标签 c gcc static-libraries

当我如下在 log2() 中传递常量值时

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

int main(int argc, char* argv[]) 
{
int var;
var= log2(16);
printf("%d",var);
return 0;
}

gcc prog.c(没有错误) 4

但是当我在函数 log2(var) 中传递变量时给出错误 对 log2 的 undefined reference 我需要链接库,即 -lm

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

int main(int argc, char* argv[]) 
{ 
int var,i;
i= log2(var);
printf("%d",i);
return 0;
}

给出错误

undefined reference to `log2'

最佳答案

在第一段代码中,编译器将 log2(16) 替换为常量 4。编译器通常以这种方式优化常数数学。这就是您看不到错误的原因。

查看生成的代码以进行确认。这是您的第一个版本:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    $4, 28(%esp)
    movl    $.LC0, %eax
    movl    28(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    movl    $0, %eax
    leave
    ret

没有调用 log2。编译器已将其替换为常量 4 (movl $4, 28(%esp))。

这是你的第二个版本:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $48, %esp
    fildl   40(%esp)
    fstpl   (%esp)
    call    log2
    fnstcw  30(%esp)
    movzwl  30(%esp), %eax
    movb    $12, %ah
    movw    %ax, 28(%esp)
    fldcw   28(%esp)
    fistpl  44(%esp)
    fldcw   30(%esp)
    movl    $.LC0, %eax
    movl    44(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    movl    $0, %eax
    leave
    ret

如您所见,此版本中有一个call log2。这就是第二个版本需要 -lm 的原因。

关于c - 在 gcc 中使用数学函数时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15737932/

相关文章:

无法在 C 中将结构指针作为函数参数传递

c - 带有消息的 assert()

c++ - 如何找到机器上为 C 或 CPP 安装/可用的库?

c++ - Libpthread 链接器错误

c - c语言如何从文件中读入数组

c - union 和内存管理

objective-c - 从 GCC 中的单独文件内联函数

c - Newlib 在 ARM 嵌入式系统中首次调用时无法分配堆

c++ - 如何构建依赖于 libcurl 的静态可执行文件?

c++ - 调用 Clock::getElapsedTime() 时 SFML 2.0 崩溃