这是我的代码
#include<iostream>
//#include<cmath>
double sqrt(double);
int main()
{
using namespace std;
cout << sqrt(16) << endl;
cin.get();
return 0;
}
我只是在探索c ++,据说[C ++ Primer,Lippman]这种形式的函数原型应该正常工作。
如果我替换double sqrt(double);
我的代码有效
使用注释行#include<cmath>
但是为什么另一种方法会抛出这个错误:
$ g++ so_c++1_FntnPrototype.cpp -lm
/tmp/cc45Ec4F.o: In function `main':
so_c++1_FntnPrototype.cpp:(.text+0x22): undefined reference to `sqrt(double)'
collect2: error: ld returned 1 exit status
答案 0 :(得分:1)
保留库函数的名称。 C ++ 14 [extern.names] / 3:
使用外部链接声明的标准C库中的每个名称都保留给实现,以便在名称空间
extern "C"
和全局名称空间中用作std
链接的名称。使用外部链接声明的标准C库中的每个函数签名都保留给 实现用作具有extern“C”和extern“C ++”链接的函数签名,或者作为全局命名空间中命名空间范围的名称。
保留给实现意味着如果您尝试声明名称,则它是未定义的行为:
如果程序在保留它的上下文中声明或定义名称,除了本条款明确允许的名称外,其行为是未定义的。
Undefined behaviour意味着任何事情都可能发生;在这种情况下,包括无法编译的代码。
答案 1 :(得分:0)
问题是数学库(-lm
)中的函数具有C链接。如果您修改sqrt
原型以指示它应该具有C链接,那么您的程序链接正常:
#include<iostream>
extern "C" double sqrt(double);
int main()
{
using namespace std;
cout << sqrt(16) << endl;
cin.get();
return 0;
}
(顺便说一下。这就是使用头文件的原因 - 所以你不必记住这些细节)