我只是在学习C ++。使用g ++版本3.2.3进行编译," g ++ hworld.cpp":
double sqrt(double);
int main(){
double x = sqrt(1515.15);
return 0;
}
编译好,但如果我们用" sqrtfoo"替换sqrt。编译器会说sqrtfoo不能用作函数。我以为我必须包括cmath,但我猜不是吗?有人可以在任何包含之前解释我的程序可以访问的内容吗?为了比较,gcc不允许我这样做,说"未定义引用' sqrt'。"谢谢。
答案 0 :(得分:3)
您不需要包含cmath
,因为您的代码已经有sqrt
的原型,第一行。
答案 1 :(得分:2)
正如现有的答案所解释的那样,double sort(double)
提供了一个原型,让编译器知道函数存在。
但是你也提到过这在GCC下不起作用。构建C或C ++程序时,源代码将编译为对象格式。然后将目标文件链接在一起以形成可执行文件。
要查看此操作,请尝试
gcc -c hello.c
这告诉GCC编译(-c)源文件hello.c。假设hello.c存在且没有错误,您将在当前目录中找到hello.o。现在试试
gcc -o hello hello.o
这告诉GCC将hello.o与相应的系统库链接,并生成一个名为“hello”的输出文件。如果hello.c使用数学函数,您还需要在数学库中链接:
gcc -o hello hello.o -lm
“ - l”用于告诉gcc包含额外的库(超出默认的“libc”C库)。 “m”指的是“libm”,它是包含sqrt
的数学库。如果你的程序只使用一个源文件,那么通常会在一个命令中隐式地询问GCC编译和链接:
gcc -o hello hello.c -lm
现在回答你的问题。 GCC不会编译上面的代码,因为你没有要求它在数学库中链接。但是g ++没问题。 Stack Overflow上已经有一个非常similar question。根据其接受的答案,
C ++运行时libstdc ++需要libm,所以如果你编译一个C ++ 使用GCC程序(g ++),您将自动获得libm链接。
由于“libstdc ++”是C ++语言运行时库,因此默认情况下它包含在g ++中。由于它依赖于libm,链接器会在生成最终二进制程序时自动加载libm。
答案 2 :(得分:1)
头文件仅包含声明(签名),并且您在第一行中包含了一个(原型:double sqrt(double)
)。
编译器编译它就好了,因为你已经说过定义了这个函数。编译后发生的步骤负责实际查找该函数定义。它被称为linking
,在此阶段,链接器会查找这些定义。如果sqrtfoo
找不到任何内容,而sqrt
则会在某个标准库中找到它(我不知道这里的详细信息)。