Including .cpp files
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.
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.
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.