簡體   English   中英

僅當參數不是常量時,來自math.h的sqrt才會導致鏈接器錯誤“對sqrt的未定義引用”

[英]sqrt from math.h causes linker error “undefined reference to sqrt” only when the argument is not a constant

我創建了一個小程序,如下所示:

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

  int main(int argc, char *argv[]) {
    int i; 
    double tmp;
    double xx;

    for(i = 1; i <= 30; i++) {
      xx = (double) i + 0.01;

      tmp = sqrt(xx);
      printf("the square root of %0.4f is %0.4f\n", xx,tmp);
      sleep(1);
      xx = 0;
    }

    return 0;
 }

當我嘗試使用以下命令對此進行編譯時,出現編譯器錯誤。

gcc -Wall calc.c -o calc

返回:

/tmp/ccavWTUB.o: In function `main':
calc.c:(.text+0x4f): undefined reference to `sqrt'
collect2: ld returned 1 exit status

如果我將sqrt(xx)調用中的變量替換為sqrt(10.2)之類的常量,則編譯就可以了。 或者,如果我明確鏈接如下:

gcc -Wall -lm calc.c -o calc

它也可以正常工作。 誰能告訴我是什么原因造成的? 我很長時間以來一直是C程序員(並且我已經使用math.h編寫了類似的小程序),但從未見過這樣的事情。

我的gcc版本如下:

$ gcc --version
gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$

如果您在使用sqrt(10.2)的情況下查看編譯器的輸出,我敢打賭,您會發現實際上並未調用sqrt()

發生這種情況是因為GCC可以識別幾種可以特殊處理的功能。 這樣,它就可以進行某些優化,在本例中為“ 常量折疊” 這樣的特殊功能稱為內置功能。

如果必須將其鏈接到數學庫(因為要使用變量對其進行調用),則需要顯式鏈接。 一些操作系統/編譯器會為您執行此操作,這就是為什么您過去可能沒有注意到的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM