真的很奇怪,有时 gcc 找不到 sqrt 的引用,但有时 gcc 可以

It's really strange that sometimes gcc can't find reference of sqrt but sometimes gcc can

我试过这个代码

/*main.c*/
#include <stdio.h>      /* printf */
#include <math.h>       /* sqrt */

int frequency_of_primes (int n) {
  int i, j;
  int freq = n - 1;
  for (i = 2; i <= n; ++i)
  for (j = sqrt(i); j > 1; --j)
    if (i%j==0) {--freq; break;}
  return freq;
}

int main() {
  printf("%f\n", sqrt(4.0));
  return 0;
}

并用 gcc main.c 编译它,它报告说 undefined reference tosqrt'. I already know add-lm` 选项可以解决这个问题。但真正让我吃惊的是:

#include <stdio.h>      /* printf */
#include <math.h>       /* sqrt */

// int frequency_of_primes (int n) {
//   int i, j;
//   int freq = n - 1;
//   for (i = 2; i <= n; ++i)
//   for (j = sqrt(i); j > 1; --j)
//     if (i%j==0) {--freq; break;}
//   return freq;
// }

int main() {
  printf("%f\n", sqrt(4.0));
  return 0;
}

main 函数也调用了 sqrt,但是 ld 没有报告任何错误。

那是因为优化器正在处理您正在使用的常量情况。

问题出在frequency_of_primes()里面的sqrt(i)调用,main()里面的调用优化掉了。您可以通过阅读为后一种情况生成的代码来弄清楚这一点,它只会加载一个常量 2.0 并完成它。