include directories vs. lib directory concept question - c++

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 between using include files and a static lib file to call functions. In my mind, the include files have functions that one can call just like .lib files.

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.
* This is not strictly true, but is sufficient for our purposes here.

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 not compiled again.

Include files typically contain the declaration of a symbol (a function, a variable). This lets 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.

Related

Getting 'multiple definition' error and I have no clue why [duplicate]

This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.

Is there a way to create different type but same base inheritance objects defined in a shared library? [duplicate]

This question already has answers here:
Is it a good practice to place C++ definitions in header files?
(17 answers)
Closed 2 years ago.
I'm wondering if it's a good practice to store C++ regular functions, not methods(the ones in classes) inside header files.
Example:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
And Use it like this:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Is this a good a good practice?
Thanks in advance!
If you want to use a function in multiple source files (or rather, translation units), then you place a function declaration (i.e. a function prototype) in the header file, and the definition in one source file.
Then when you build, you first compile the source files to object files, and then you link the object files into the final executable.
Example code:
Header file
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b); // Function prototype, its declaration
#endif
First source file
#include "functions.h"
// Function definition
int add(int a, int b)
{
return a + b;
}
Second source file
#include <iostream>
#include "functions.h"
int main()
{
std::cout << "add(1, 2) = " << add(1, 2) << '\n';
}
How you build it depends very much on your environment. If you are using an IDE (like Visual Studio, Eclipse, Xcode etc.) then you put all files into the project in the correct places.
If you are building from the command line in, for example, Linux or OSX, then you do:
$ g++ -c file1.cpp
$ g++ -c file2.cpp
$ g++ file1.o file2.o -o my_program
The flag -c tells the compiler to generate an object file, and name it the same as the source file but with a .o suffix. The last command links the two object files together to form the final executable, and names it my_program (that's what the -o option does, tells the name of the output file).
No. After preprocessing, each source file will contain the header file. Then, at the linking stage you will end up with a multiple definition error because you will have multiple definitions of the same function.
Using inline or static will get rid of the linking error. Unless you want the function to be inline, it is best to declare the function in the header and define it in a single source file and link it.
If you declare the function as inline, then each of its function call in the source file will be replaced with the code inside the inlined function. So, there's no extra symbol defined.
If you declare the function as static, then the function symbol will not be exported from the translation unit. Therefore, no duplicate symbols.
Adding to what is said above, a function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function , is implicitly an inline function. So you do not need to explicitly write inline for the mentioned situations.
No. If you import the same header from two files, you get redefinition of function.
However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.
Using static also works because of fact that static functions are not exported from object file and in this way can't interfere with other functions with the same name during linkage.
It's also OK to define member functions inside the class in header as C++ standard considers them as inline.

Including .cpp files

I have read in places like here that you have to include .h files and not .cpp files, because otherwise then you get an error. So for example
main.cpp
#include <iostream>
#include "foop.h"
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
foop.h
#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif
foop.cpp
int foo(int a){
return ++a;
}
works, but if I replace #include "foop.h" with #include "foop.cpp" I get an error (Using Dev C++ 4.9.9.2, Windows):
multiple definition of foo(int)
first defined here
Why is this?
What include does is copying all the contents from the file (which is the argument inside the <> or the "" ), so when the preproccesor finishes its work main.cpp will look like:
// iostream stuff
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.
There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.
The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.
When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cpp and pasted it into main.cpp.
So when you compile main.cpp, the compiler emits a main.obj that contains the executable code for two functions: main and foo.
When you compile foop.cpp itself, the compiler emits a foop.obj that contains the executable code for function foo.
When you link them together, the compiler sees two definitions for function foo (one from main.obj and the other from foop.obj) and complains that you have multiple definitions.
This boils down to a difference between definitions and declarations.
You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.
In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.
Note: if you change foo to be static, you would have no linking errors. Despite the lack of errors, this is not a good thing to do.
You should just include header file(s).
If you include header file, header file automatically finds .cpp file.
--> This process is done by LINKER.
Because of the One Definition Rule (probably1).
In C++, each non-inline object and function must have exactly one definition within the program. By #includeing the file in which foo(int) is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).
You can make a function inline to override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #include a CPP file.
There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.
1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactly the same as the code you're compiling.
Because your program now contains two copies of the foo function, once inside foo.cpp and once inside main.cpp
Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
return ++a;
}
int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}
and foo.cpp
int foo(int a){
return ++a;
}
hence the multiple definition error
So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):
Visual Studios: .cpp file > right click > properties > configuration properties >
general > excluded from build > yes
I believe you can also exclude the file when compiling from the command line.
I want to clarify something: including header files is not neccessary to make the linker understand what you want. You can just declare it and it will be linked fine.
main.cpp:
#include <iostream.h>
//not including "foop.cpp"!
int foo(int a);
int main(){
std::cout << foo(4) << std::endln;
}
foop.cpp:
int foo(int a){
return a++;
}
I don't encourage doing like this, but know that headers are not some magic which you have to follow to make the code compile.
Using ".h" method is better
But if you really want to include the .cpp file then make foo(int) static in foo.cpp

C: Using functions from files within in the same project

My question does not link to a direct example, but is more of a question as a whole. When I was coding with C++, I found (after looking through some threads) that in order to use functions from different files that are in the same project, I would either need a header file. So, for example, if I have the main function in a file called "main.cpp" and I wanted to use a function, "prob1()" in another file called "problem1.cpp", I would need to use a header file.
What is confusing me is why I do not have to worry about this for programming in C? When I was programming in C, in order to use functions from different files, I could call the function directly.
Any help/explanation is appreciated. Thanks!
Your C compiler can implicitly declare the function, but you should be doing so yourself. If you turn up the warnings, you'll see something like:
file1.c: warning: implicit declaration of function ‘func_from_f2’
When file1.c is being compiled, this implicit declaration will be used to create an object file and then when linking you have to just hope that the function actually does exist and the declaration is correct so that the object files can be linked together successfully.
If not, the linker will give you an error somewhere along the lines of:
undefined reference to `func_from_f2'
You also don't necessarily need a header file, you can simply include the declaration/prototype of the function in your source file (the #include directive essentially does this for you). ie. the below will work fine without warnings:
file1.c
void func_from_f2(void);
int main(void)
{
func_from_f2();
return 0;
}
file2.c
#include <stdio.h>
void func_from_f2(void)
{
puts("hello");
}
However, it's usually best practice that you do use a header file:
file1.c
#include "file2.h"
int main(void)
{
func_from_f2();
return 0;
}
file2.h
#ifndef FILE2_H
#define FILE2_H
void func_from_f2(void);
#endif
file2.c
#include <stdio.h>
#include "file2.h"
void func_from_f2(void)
{
puts("hello");
}
In C, the compiler will guess the correct prototype if you haven't provided one. It very often guesses wrong, and then your program breaks.
Whether C or C++, it's always a good idea to put forward declarations in a header file that also gets #included into the implementation file, where the compiler can check for mismatch.

about headers in C++ when I should use them?

Question about header files in C++: when I should use them. If I write small program should I create header file or can I just declare my classes in .cpp files? What is a good practice? If you give links to articles about it, it would be good. I could not find good ones.
Use header files when you need to share information between several source files. The header file, used carefully, will ensure consistency between a file defining some functionality and other files using that functionality.
When a program consists of a single (source) file, there is no need to create a header. When a program needs more than one source file (say two source files), there must be at least one function or variable 'shared' between the two files (because if there wasn't, one of the files would be redundant). You should have a header to describe the shared function or variables so that the producer and consumer agree on the common functionality.
The corollary is that a header should not describe anything not needed by the consumers of the functionality. Just because the implementation needs to use some second header, the consumer should not be made to include it. If the second header provides definitions used in the interface, then it should indeed be included in the common header.
OK - lots of verbiage. A concrete example:
source1.h
extern int somefunc(int, int);
source1.cpp
#include "source1.h"
int somefunc(int a, int b)
{
return a + b;
}
program.cpp
#include <iostream>
#include "source1.h"
using namespace std;
int main()
{
int x = somefunc(1, 3);
cout << "somefunc(1, 3) is " << x << endl;
}
The header here is necessary to provide the assurance that everything is consistent. Both source1.cpp and program.cpp must include the header to ensure the consistency.
Note that if somefunc() was defined in program.cpp there would be no point in providing the header.
Now suppose we modify somefunc():
source1.cpp - revised
#include "source1.h"
#include <iostream>
using namespace std;
int somefunc(int a, int b)
{
cout << "a = " << a << ", b = " << b << endl;
int x = a + b;
cout << "x = " << x << endl;
return x;
}
Superficially, you could revise source1.h so it includes <iostream>, but that would be a bad move. The interface of the function defined, somefunc(), does not depend on <iostream>, so the header should not include <iostream>.
Header files are always a good idea but strictly speaking you don't need them. Especially when using multiple .cpp files it's strongly recommended to use them.
The rule I used before "always use them" was: any cpp that has its functions accessible from other cpp files should use a header file to "export" the functions.
Best practice: always use header files.
Another reason why you should use header files
when you distributing your binaries. You provide the header file and the dll file to your clients.