Jordanss10
Jordanss10

Reputation: 4121

How are function definitions determined with header files?

When using separate files in C++, I know that functions can be declared using header files like this:

// MyHeader.h

int add(int num, int num2);

// MySource.cpp

int add(int num, int num2) {
    return num + num2;
}

// Main.cpp

#include "MyHeader.h"
#include <iostream>

int main() {
    std::cout << add(4, 5) << std::endl;
    return 0;
}

My question is, in this situation, how does the compiler determine the function definition of add(int,int) when MyHeader.h and Main.cpp have no references at all to MySource.cpp?

As, if there were multiple add functions (with the same arguments) in a program, how can I make sure the correct one is being used in a certain situation?

Upvotes: 1

Views: 80

Answers (3)

Dan Korn
Dan Korn

Reputation: 1294

The compiler doesn't compile header files; it compiles source files. It will include the code in the header when the header is #included in a source file being compiled, but on its own, the header file doesn't "do" anything.

Also, the compiler doesn't worry about whether a function is defined or not. It just compiles against function declarations. It's the linker that resolves the definitions of functions.

You don't need to include a definition of a function at all, unless it's being called by some other code you need to link.

As to your question, "If there were multiple add functions (with the same arguments) in a program, how can I make sure the correct one is being used in a certain situation?": It depends on the linker and the settings, but generally, if you have more than one definition of a function with the same signature, the linker will issue an error stating that the function is multiply defined.

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 489988

The function declaration gives the compiler enough information to generate a call to that function.

The compiler then generates an object file that specifies the names (which, in the case of C++ are mangled to specify the arguments, namespace, cv-qualifiers, etc.) of external functions to which that object file refers (along with another list of names it defines).

The linker then takes all those object files, and tries to match up every name that something refers to but doesn't define with some other object file that defines the same name. Then it assigns and fills in addresses, so where one object file refers to nameX, it fills in the address it's assigning to nameX from the other file.

At least in a typical case, the object files it looks at will include a number of libraries (standard library + any others you specify). A library is basically just a collection of object files, shoved together into a single file, with enough data to index what data is which object file. In a few cases, it also includes some extra meta-data to (for example) quickly find an object file that defines a specific name (obviously handy for the sake of faster linking, but not really an absolute necessity).

If there are two or more functions with exactly the same mangled name, then your code has undefined behavior (you're violating the one definition rule). The linker will usually give an error message telling you that nameZ was defined in both object file A and object file B (but the C++ standard doesn't really require that).

Upvotes: 3

Christian Hackl
Christian Hackl

Reputation: 27518

The compiler does not "determine" (you mean "know") the function definition. The linker does. You have just discovered why the build process consists of compiling and linking.

So, basically, the compiler produces two object files here. One which contains the definition of add and one which just refers to the "unknown" function add. The linker then takes the two object files and puts the reference and definition together. Of course, that's just a very simple explanation, but for a beginner, that's all you need to know.

Upvotes: 3

Related Questions