-2

This is my code

#include<iostream>
//#include<cmath>
double sqrt(double);

int main()
{
    using namespace std;

    cout << sqrt(16) << endl;
    cin.get();

    return 0;
}

I am only exploring into c++ and supposedly[C++ Primer, Lippman] this form of function prototyping should be working. My code works if I replace double sqrt(double); with the commented line #include<cmath>

But why does the other method throw this error:

    $ 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
Sharan
  • 59
  • 8

2 Answers2

1

Names of library functions are reserved. C++14 [extern.names]/3:

Each name from the Standard C library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.

Each function signature from the Standard C library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.

Being reserved to the implementation means that it's undefined behaviour if you try to declare the name:

If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.

Undefined behaviour means that anything can happen; in this case that includes the code failing to compile.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

The problem is that functions in math library (-lm) have C linkage. If you modify sqrt prototype to indicate that it should have C linkage, your program links fine:

#include<iostream>

extern "C" double sqrt(double);

int main()
{
    using namespace std;

    cout << sqrt(16) << endl;
    cin.get();

    return 0;
}

(BTW. that's why header files are used - so you don't have to remember about such details)