Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do C++ find the function declaration

Tags:

c++

methods

I need help translating a concept from Java to C++.

In Java, when you create a class and give it methods (functions), you must define the function in that class so that it can be properly called by any class instance that might want to. For example, in the class Employee you'd declare and define the method salaryRaise(int amount). Whenever an Employee object wants to use it, it calls Employee.salaryRaise(i) and Java knows exactly where to find it - in the Employee class.

In C++, functions are declared in .h files and then defined somewhere else. How does the compiler know where to find this method?

like image 897
CodyBugstein Avatar asked Dec 01 '22 20:12

CodyBugstein


2 Answers

That is really the job of the linker, not the compiler. The compiler will call the function referencing a symbol that is yet undefined. The linker will then get the different translation units and resolve the symbols by name (that is, the mangled names that encodes additional information as the namespaces, types of the arguments...)

like image 80
David Rodríguez - dribeas Avatar answered Dec 05 '22 15:12

David Rodríguez - dribeas


You declare the function in the header (.h) file. That header file then gets #includeed in any other files where you need to use the function. This satisfies the compiler, because it knows the signature of the function and how to call it.

The function is then defined in the source (.cpp) file. The source file includes it's own header file, so that when you compile it, you end up with an object file containing the complete compiled code for that function.

The linker then links any parts of your code where you've called the function (i.e. the files where you included the header), with the actual code for that function.

EDIT with example:

Foo.h:

#ifndef FOO_H
#define FOO_H

class Foo
{
public:
   int fooFunction(double a);
};

#endif

Foo.cpp:

#include "Foo.h"

int Foo::fooFunction(double a)
{
   // Function definition
   return 1;
}

Compiling Foo.cpp generates Foo.obj which contains the complete definition for fooFunction. So far so good.

Bar.h:

#ifndef BAR_H
#define BAR_H

#include "Foo.h"

class Bar
{
public:
   void barFunction();
};

#endif

Bar.cpp:

#include "Bar.h"

void Bar::barFunction()
{
   Foo foo;
   int returnValue = foo.fooFunction(2.0);
}

Bar.cpp includes Bar.h which in turn includes Foo.h. When Bar.cpp gets preprocessed therefore, the declarations for Foo::fooFunction are inserted at the top of the file. So, when the statement int returnValue = foo.fooFunction(2.0); is compiled, the compiler knows how to emit the machine instructions to call fooFunction because it knows the type of the return value (int) and it knows the types of the parameters (a double, and an implicit this pointer for the foo object). Because no function definition was provided, the function will not be inlined (inlining means the entire code for the function is copied into the point at which it is called). Instead, a pointer to the memory address of the function is used to call it. Because a pointer is being used, the compiler doesn't care about the definition - all it needs to know is "I need to call a function X at memory location Y with parameters A and B, and I need to have an int sized memory section ready to store the return value, and I'll assume that the code at that address knows how to perform the function". However, the compiler has no way to know what the address of that function will be in advance (because the function definition lives in a separate .cpp file and will be part of a separate compilation job AKA translation unit).

That's where the linker comes in. Once all the translation units have been compiled (which could be in any arbitrary order), the linker goes back to the compiled code for Bar.cpp and links the two together by filling in the address for the now compiled definition of fooFunction at the point at which it is called in Bar.cpp, thus making the compiled code fully executable.

like image 28
JBentley Avatar answered Dec 05 '22 14:12

JBentley