Question

I am just learning C++. Compiling with g++ version 3.2.3, "g++ hworld.cpp":

double sqrt(double);
int main(){
    double x = sqrt(1515.15);
    return 0;
}

That compiles fine, but if we were to replace sqrt with "sqrtfoo" the compiler would say sqrtfoo cannot be used as a function. I thought I would have to include cmath, but I guess not? Can someone please explain what my program has access to before any includes? For comparison, gcc does not allow me to do this, saying "undefined reference to 'sqrt'." Thank you.

Was it helpful?

Solution

As the existing answers explain, the double sort(double) provides a prototype to let the compiler know that the function exists.

But you also mentioned that this doesn't work under GCC. When you build a C or C++ program, the source code is compiled into object format. The object files are then linked together to form an executable.

To see this in action, try

gcc -c hello.c

This tells GCC to compile (-c) the source file hello.c. Assuming that hello.c exists and has no errors, you'll find hello.o in the current directory. Now try

gcc -o hello hello.o

This tells GCC to link hello.o with the appropriate system libraries, and to generate an output file called "hello". If hello.c uses math functions, you'll also need to link in the math library:

gcc -o hello hello.o -lm

"-l" is used to tell gcc to include extra libraries (beyond the default "libc" C library). "m" refers to "libm", which is the math library containing sqrt. If your program uses only one source file it's common to ask implicitly GCC to compile and link in a single command:

gcc -o hello hello.c -lm

Now to your question. GCC won't compile the above code because you haven't asked it to link in the math library. But g++ is okay with it. There's a very similar question already on Stack Overflow. According to its accepted answer,

the C++ runtime libstdc++ requres libm, so if you compile a C++ program with GCC (g++), you will automatically get libm linked in.

Since "libstdc++" is the C++ language runtime library, it's included by g++ by default. And as it depends on libm, the linker automatically loads libm while producing the final binary program.

OTHER TIPS

You don't need to include cmath because your code has a prototype for sqrt in it already, the very first line.

Header files hold only declarations (signatures), and you've included one in the first line (prototype: double sqrt(double)).

The compiler compiles it just fine, because you've stated that somewhere this function is defined. The step that occurs after compiling is responsible for actually looking for that function definition. It's called linking, and during that phase linker lookups those definitions. In case of sqrtfoo it cannot find anything, whereas in case of sqrt it finds it in some standard library (I do not know the details here).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top