What is the difference between linking to include files versus linking to lib files?
I am fairly new to C/C++ and I\'m having a hard time figuring out the difference be
In C++ (and C and other similar languages) a function is said to have both a declaration and a definition.
The declaration is simply a short statement that declares that the function exists, and what its interface looks like. Consider a basic function add
that adds two integers together. Its declaration might look like the following:
int add(int, int);
This means "there exists a function add
that takes two integers and returns an integer". It does not specify what the function actually does, despite the fact that we can make a good guess based on its name.
The definition of the function is where we define exactly what the function does. This might be what you consider to be the actual function code. Using the add
function as an example:
int add (int a, int b)
{
return a + b;
}
So how does this fit with your question? Well, suppose we have a number of math functions in math.cpp
:
// math.cpp
int add (int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
And also suppose we decide to use some of these in our main function in main.cpp
:
// main.cpp
#include <iostream>
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
If you try to compile main.cpp
as it is, it will complain that it doesn't know what add
and sub
are. This is because you are trying to use them without declaring that they exist - which is exactly what a declaration is for. So you might do the following:
// main.cpp
#include <iostream>
int add(int, int);
int sub(int, int);
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
This would work, but is not very flexible. If we add a new function mul
, we need to go and add its declaration to main.cpp
and every other .cpp
file that uses it (which is a lot of work if you have a lot of .cpp
files). So what we do is instead we put all the declarations into a single file (say, math.h
) so we only have to maintain the list of declarations in a single spot. Then, we simply include math.h
into any file that uses the math functions. This is the purpose of header files (a.k.a. include files).
This works great, but could be even better. As it is, we have a main.cpp
file, and a math.cpp
file, both of which are compiled every time you compile the program*. If your math functions don't change at all, surely it's better to compile them once and just insert the pre-compiled definitions into your executable whenever you recompile main.cpp
? That is exactly the purpose of .lib
files. They contain the pre-compiled code for definitions of the relevant functions. You still need the include file to let you know what functions exist in the lib.
The purpose of the linking stage of compilation is to take these pre-compiled functions and the functions you have just compiled, and roll them together into a single executable file.
Essentially, you can look at a static lib as the pre-compiled code for a number of predefined functions, and its matching include file as a tool to let any code wanting to use those functions know which are available and what their description is.
to provide a simpler answer:
.lib files are precompiled libraries. if you include a .lib, you also need to include the .h/hpp header files, so your compiler knows how to access the functions in the .lib.
when you compile your program, all the functions used from the lib are only linked, they are note compiled again.
Include files typically contain the declaration of a symbol (a function, a variable). This let's the compiler know that a name is defined (in the header) or elsewhere (in the case of a declaration):
a.h:
void a_useful_function(); //declaration
but you can also have a definition:
a.h:
void a_useful_function()
{
//... do something
}
Libraries are an accumulation of functions which get typically exposed by headers. The header is usually the interface to a library that you will be linking against.
There exist header only libraries however that have their declarations and definitions code in the same file.
You mention include directories in your question. The include directories are the places where the compiler searches to resolve an #include "a.h" preprocessor directive.
But there are also library directories where the linker searches for needed libraries that usually provide implementations (definitions) to the declarations in your headers.