//myheader.h
namespace abc{
int func(int x) { return 10 + x;}
inline int callfunc(int a){ return func(a); }
}
//global.h
int func(int x){ return 10 + x; }
In the example above, when the code is compiled, and even if the inline function are not called at any place for now, it returns an error to resolve the ambiguity for the func(int x). Why doesn't inline function take the existing definition that is already present in the namespace abc?
Your error is not reproducible from posted code - these headers compile without problems when included in single .cpp file. So you really should post your .cpp files. It's .cpp files that are actually compiled, not headers, so without them we don't get the whole picture.
You should've posted an actual error, not just your impression of it. With your description we can't even be sure if it's compiler error or linker error.
Nevertheless, I'll propose some possible solutions for your problem.
Try to specify namespace in call to the func:
inline int callfunc(int a){ return abc::func(a); }
You really shouldn't define non-inline functions in headers, you'll get linker errors if you include your headers in more than one .cpp file.So you should keep definitions in .cpp and only declarations in .h files like it was meant to be.
Related
I'm too much confused why it's an error to write the same function in two different cpp files?
what if both want to use that function? and why this should ever cause an error, the function is written in to separate files...
a.cpp:
#include "test.h"
b.cpp:
#include "test.h"
test.h
int getMin(int x,int y)
{
return x;
}
plus, why changing test.h to the following won't fix the problem:
#ifndef UNTITLED1_A_H
#define UNTITLED1_A_H
int getMin(int x,int y)
{
return x;
}
#endif
If you define a function twice, the linker will see 2 definitions of the same function, which is not allowed. (even though each .cpp that includes this header file sees only one definition, which is why adding header guards doesn't help here).
One option is to only write the declaration of the function in the .h file, and write the definition in a separate .cpp file. (this is the more common implementation).
If you want to define the function inside the header file, then it needs to be inline, like this:
inline int getMin(int x,int y)
{
return x;
}
Note that if you do the second option, then all files that include this header will need to be recompiled, if you change the internals of this function (this is probably not a good idea, when the interface doesn't change).
You need to make this function "inline" and it will work.
The following quote from c++ primer book confuse me a lot
Unlike other function, inline and constexpr functions may be defined
multiple times in the program. After all, the compiler needs the
definition, not just the declaration, in order to expand the code.
However, all of the definitions of a given inline or constexpr must
match exactly. As a result, inline and constexpr functions normally
are defined in headers.
-- C++ primer 5th Ed, 240 pp
"may be defined multiple times in the program" This quote confuse me a lot. As far as I understand, declaration can be made multiple time, but definition is only needed once.
can someone give me an example why there is a multiple definition.
In a header file (lets call it foo.h) you can have
inline int foo() { /* do stuff */ }
Now if you include foo.h in a couple cpp files then foo will be defined in each of them, which would be a multiple definition error. Since foo is marked as inline though, it is okay because all of the definitions are the same.
As far as I understand, declaration can be made multiple time, but definition is only needed once
The compiler works on translation units (basically a cpp file) and in it, it can do all sorts of optimizations but function inlining and constexpr require that the compiler know the definition of the function. That means each translation unit needs the definition of the function in it. We use inline to make that okay, otherwise it would be a multiple definition error.
As an example. This version isn't valid.
// main.cpp
inline int square(int num) {
return num * num;
}
inline int square(int num) {
return num * num;
}
int main()
{
return square(2);
}
https://godbolt.org/z/nlSbxg
But when you have it in multiple .cpp files (aka. translation units) it is ok because it is now linker job to do right thing.
// b.cpp
inline int square(int num) {
return num * num;
}
// main.cpp
inline int square(int num) {
return num * num;
}
int main()
{
return square(2);
}
Build: gcc main.cpp b.cpp
Same way works #include it will place code in those .cpp files that's all.
Of course if body of function is inlined, then nothing to link so no problem :)
If compiler decides to do an out-of-line version you end up with more than one object file (.o) having definition for the same "inline" function. Such definition will be marked.
Thanks to that mark linker won't yield that it has found multiple definitions and just pick first one that it finds.
So if all definitions are truly the same, then fine! We will get into troubles if we have different body of such function. Example in file b.cpp
// b.cpp
inline int square(int num) {
return 1;
}
It is undefined behavior to have multiple different definitions of the same inline function. It will compile of course but what we get? It depends on linker choice :D
I think the problem is that there are multiple things we can mean by "define." When you write an inline function in a header file, it's "defined" just once in the sense that there is only a single function with that name in your source code.
But that's not how the compiler and linker see the world. If you have an inline function foo in a header file that's called from a.cpp and b.cpp, then the complete compiled version of that function will be included in both a.obj and b.obj. The linker resolves the issue by picking just one of those compiled versions to include in your final binary.
Note that I'm glossing over significant details here, but this is the general idea (and what I think your textbook is eluding to).
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
I'm using multiple C++ files in one project for the first time. Both have need to include a protected (#ifndef) header file. However, when I do that, I get a multiple definition error.
What I have is two one .cpp file that calls the header directly, and one indirectly (Another include includes it) and then two other header files that include it.
So what do I need to do to get rid of the error?
ERROR:
obj\Debug\main.o||In function Z14sortLibQtyTest4BookS_':|
[PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'
CODE:
bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }
It should be mentioned that this isn't the only function giving me problems, probably more than ten are, and some aren't so short and sweet. Also, the functions are needed in multiple files.
You have two options to solve this multiple definition problem: Mark the method inline, or put the definition in a .cpp file.
1) Mark the method inline:
// Foo.h
inline bool foo(int i) { return i = 42; }
2) Put the definition in a .cpp file:
// Foo.h
inline bool foo(int i); // declaration
// Foo.cpp
bool foo(int i) { return i = 42; } // definition
Whether the method is actually inlined by the compiler in the first case is irrelevant here: inline allows you to define a non-member function in a header file without breaking the one definition rule.
The ".cpp" and ".h" suffixes are largely a matter of convention. As far as the compiler is concerned, where a line of code came from is irrelevant. When you #include that function into your .cpp files, you are implementing that function in that .cpp file.
So when the compiler is done and it asks the linker to knit together the code from your two cpp files, it finds a conflict: two functions with the same name and fingerprint (arguments and return). This is an error.
You need to either:
a. Put the implementation in one source file, and just leave a prototype declaration in the header
// .h
extern bool sortLibQtyTest(Book a, Book b);
// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }
b. Mark the function as inline: when you call the function, the compiler will insert copies of the function body as needed which can be wasteful, but often times the compiler can figure out the efficient thing to do.
inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
c. Mark the function as "static" which tells the compiler to create a copy of the function for every source file that includes it, but not to expose it to the linker. If some source files include the header without using the function, the compiler has to detect this and remove it - which not all compilers/optimization levels do, so it can be doubly wasteful.
static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }
d. Avoid the downsides of c, mark it static inline
static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
If the Line you quoted after "CODE" is in a header file you can either:
add inline to the definition or
remove the function body from the header and put it into 1 (and only 1) of your source files.
I have a file iforce2d_topdown_car.h in a demo project with an include guard like so:
#ifndef IFORCE2D_TOPDOWN_CAR_H
#define IFORCE2D_TOPDOWN_CAR_H
... source code ...
#endif
This is included in HelloWorldLayer.h, which is then included in two other files (this is all obj-c except for the iforce2d header). Everything compiles fine, but any errors I get are displayed 3 times. This annoys me, and I wonder if its symptomatic of a larger issue.
Is this expected behavior? It seems to me that if a preprocessor var is defined, then it will stay defined and next time it is included it will not be compiled. It seems that is not the case here, but I do not know why.
The TDCar(b2World *) is an inline member function because it is defined inside its class definition. That means the compiler instantiates the function and emits the corresponding warnings in every translation unit that calls this function.
Let's imagine you have the following A.h:
class A {
public:
int f(int i);
};
and A.cpp
int A::f(int i) {
int j = i;
return i + 1;
}
The compiler will compile the function A::f(int i) once and export it so every call to that function will link to the exported symbol. Therefore, the warning for the unused variable j will be emitted once: when A.cpp is compiled.
But if you write the following A.h:
class A {
public:
int f(int i) {
int j = i;
return i + 1;
}
};
Then the compiler will copy the code from the function definition directly into the source code file that calls the function. If you use that function in 3 different files, the function is compiled thrice and the warning is emitted thrice.
As each file is compiled individually, the compiler cannot know the warning was already emitted for another file.
Xcode should be clever enough to recognize the three warnings as being the same and aggregate them so you only get one warning. Unfortunately, Xcode isn't that clever.