C 函数 pow() 不会在共享主机服务器中执行

C function pow() won't execute in shared hosting server

我正在尝试通过 PHP exec() 函数 运行 一个 C 程序。在我的本地主机上一切 运行 都很好,但是当 运行 在托管服务器上将它连接时,带有 pow() 函数并以变量作为参数的 C 程序将不会执行。

我问了那个主机的客服,他们说他们的服务器不支持执行C编程语言。

但令我感到奇怪的是,为什么我的另一个 C 程序 运行 在那台服务器上运行良好,只是其中一个包含变量作为参数的 pow() 的代码不会' t 运行.

这是我的代码:

PHP

public function index() {
  //runs well
  $varExec = exec(app_path() . "/Exec/checkfuncpow.exe");
  var_dump($varExec);
  echo "<br/>";
  //this the one that is not running
  $varExec = exec(app_path() . "/Exec/checkfuncpowwithvar.exe");
  var_dump($varExec);
}

结果:

字符串(8)“9.000000”

字符串(0)“”

checkfuncpow.c

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

int main() {
  printf("%f", pow((double)3, (double)2));
  return 0;
}

checkfuncpowwithvar.c

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

int main() {
  double param = 3;
  printf("%f", pow(param, (double)2));
  return 0;
}

两个代码都使用强制性 -lm 标志编译为 link 到数学库

gcc checkfuncpow.c -o ./Exec/checkfuncpow.exe -lm
gcc checkfuncpowwithvar.c -o ./Exec/checkfuncpowwithvar.exe -lm

那么最终的问题是,真的是因为服务器不支持吗?或者它应该能够 运行 但客户支持没有关于这个问题的线索,所以他们只是说什么对他们来说很容易?

标准答案:如果您的托管服务不支持执行 C 程序,那么您不应该这样做;首先,因为程序可能有错误或奇怪的行为(如本例),其次,因为托管服务不会在出现问题时为您提供任何支持(如本例)。

有趣的答案:这里经历的谜团可能与两件事有关:1)编译器优化; 2) 缺少数学库。

关于编译器优化,您的两个程序恰好表现不同,因为在第一种情况下(没有 param 变量),编译器将 pow((double)3, (double)2) 替换为 (double) 9.0;因此没有调用 pow(),也不需要数学库。在第二种情况下,编译器没有优化 pow() 调用,所以数学库仍然是必要的。如果我的猜测是正确的,并且你用 gcc 选项 -O3 编译你的两个程序,现在两个程序应该 运行 没有问题。

关于缺少数学库:数学库动态地linked到您的程序中(使用-lm选项);这意味着程序 运行 所在的目标平台需要安装该库。另一方面,静态 linked 库嵌入到您的程序中,因此目标平台不需要安装它们。

您可以尝试的一件事是静态 link 数学库 (libm)。不知道怎么操作就搜索主题

编辑:为了静态解决问题-link将库放入您的可执行文件中,您可以查看this Whosebug question。 TL;DR:只要库的静态版本可用,GCC 选项 -static 应该告诉编译器使用静态库而不是动态库。在libm的情况下,在我的Ubuntu 20.04盒子上,libm的静态版本可用,所以如果我用命令gcc -o program main.c -lm -static编译程序,GCC成功使用静态版本libm.