Multple c++ files causes "multiple definition" error? - c++

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.

Related

C++ defining same function twice causes error

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.

Defined multiple times for the inline function, how possible?

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).

Inline function not resolving ambiguity

//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.

C++ I have a function used in all my headers

I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.

Significance of a .inl file in C++

What are the advantages of having declarations in a .inl file? When would I need to use the same?
.inl files are never mandatory and have no special significance to the compiler. It's just a way of structuring your code that provides a hint to the humans that might read it.
I use .inl files in two cases:
For definitions of inline functions.
For definitions of function templates.
In both cases, I put the declarations of the functions in a header file, which is included by other files, then I #include the .inl file at the bottom of the header file.
I like it because it separates the interface from the implementation and makes the header file a little easier to read. If you care about the implementation details, you can open the .inl file and read it. If you don't, you don't have to.
Nick Meyer is right: The compiler doesn't care about the extension of the file you're including, so things like ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", etc. are a simple convention, to make it clear what the files is supposed to contain.
The best example is the STL header files which have no extension whatsoever.
Usually, ".inl" files do contain inline code (hence the ".inl" extension).
Those files ".inl" files are a necessity when you have a dependency cycle between header code.
For example:
// A.hpp
struct A
{
void doSomethingElse()
{
// Etc.
}
void doSomething(B & b)
{
b.doSomethingElse() ;
}
} ;
And:
// B.hpp
struct B
{
void doSomethingElse()
{
// Etc.
}
void doSomething(A & a)
{
a.doSomethingElse() ;
}
} ;
There's no way you'll have it compile, including using forward declaration.
The solution is then to break down definition and implementation into two kind of header files:
hpp for header declaration/definition
inl for header implementation
Which breaks down into the following example:
// A.hpp
struct B ;
struct A
{
void doSomethingElse() ;
void doSomething(B & b) ;
} ;
And:
// A.inl
#include <A.hpp>
#include <B.hpp>
inline void A::doSomethingElse()
{
// Etc.
}
inline void A::doSomething(B & b)
{
b.doSomethingElse() ;
}
And:
// B.hpp
struct A ;
struct B
{
void doSomethingElse() ;
void doSomething(A & a) ;
} ;
And:
// B.INL
#include <B.hpp>
#include <A.hpp>
inline void B::doSomethingElse()
{
// Etc.
}
inline void B::doSomething(A & a)
{
a.doSomethingElse() ;
}
This way, you can include whatever ".inl" file you need in your own source, and it will work.
Again, the suffix names of included files are not really important, only their uses.
Since nobody else has mentioned it:
The use of .inl files to store your inline functions can be useful for speeding up compiles.
If you only include the declarations (.h) where you need declarations, and only include inline implementations (.inl) where you need them ( i.e. probably only in .cpp and other .inl files, not .h's ), it can have a beneficial effect on your header dependencies.
This can be a significant win on larger projects with many interacting classes.
In my experience, .inl files are used to define inline functions. When they're in an .inl file, the file can be included in a header to get inline functions and in a .c file to get regular function definitions.
This way the same source can more easily work with compilers that do not have inline function supportas well as compilers that do.
They're usually used with straight C code, not often with C++ code as all C++ compilers support inline functions.
I believe it's just a naming convention for a "header" file includes inline code.
it's so that .h files can contain definitions and .inl files contain inline code which is necessary for templates.
I don't belive there is anything more to it than an naming convention to make the purpose of the file clear