I have created custom random number generators and placed their global functions in a file I called SamRandom.h. The file looks as follows:
#ifndef _SAM_RANDOM_H
#define _SAM_RANDOM_H
#include <cstdlib>
#include <ctime>
void InitialiseRandomSeed()
{
//...
}
//...
#endif
I'm working in a very complex object-oriented program that has many different components from here and there. Everytime I add a file that is anyhow related to this file, I get the following conflict message:
LaserBase.obj:-1: error: LNK2005: "void __cdecl InitialiseRandomSeed(void)" (?InitialiseRandomSeed##YAXXZ) already defined in main.obj
error: LNK1169: one or more multiply defined symbols found
On MSVC, and on MinGW I get:
In function `Z20InitialiseRandomSeedv':
SamRandom.h:8: multiple definition of `InitialiseRandomSeed()'
error: first defined here
:-1: error: collect2: ld returned 1 exit status
Why is this happening? I thought that preprocessor directive is supposed to prevent this problem from happening... this is really driving me crazy!!!
P.S.: The problem is independent of the function name.
Thanks for any efforts
When you include your file in a .cpp file the preprossesor directly copys it into that file. So when you compile that .cpp file the object file (a step the compiler always does even if you don't recognize) will contain that function. If you include it in more than one .cpp file each object file will contain the function. When the linker trys to link all object files to an executable it finds the function x-times and gives that error.
"one or more multiply defined symbols found" says it found one of your functions (or variables) more than once and doesnt know how to deal with it.
To avaoid this you should only put the signature of you function e.g.
//whatever.h
#ifndef _SAM_RANDOM_H
#define _SAM_RANDOM_H
void InitialiseRandomSeed();
#endif
in ther header file and put the implementation into a seperate .cpp file:
//whatever.cpp
#include "whatever.h"
#include <cstdlib>
#include <ctime>
void InitialiseRandomSeed()
{
//...
}
The header guards ensure that the function is not being defined multiple times in a single compilation unit (.cpp file). However, they don't prevent the function from being defined a single time in multiple compilation units. This is because the header contains the definition of the function, so every .cpp that includes the header has its own definition of the function.
You could move the definition to SamRandom.cpp and instead declare the function in the header like so:
void InitialiseRandomSeed();
Alternatively you could specify that the function is inline which would make multiple definitions acceptable:
inline void InitialiseRandomSeed()
{
//...
}
Assuming that the function is not performance-critical and does not get called frequently, I would go with the former approach. This keeps headers more readable and (in general) decreases compile times.
You could separate the definition into a .cpp file and just declare the function in the header.
Related
I am writing a library for neural nets. There are some necessary functions I needed so I separated them in a separate header file. I also provided the definition guards. I also included the header file in only one file but then also linker claims that there are multiple definitions of all the functions in the program.
The library structure is as follows:
namespace maya:
class neuron [neuron.hpp, neuron.cpp]
class ffnet [ffnet.hpp, ffnet.cpp]
struct connection [connection.hpp]
functions [functions.hpp]
the functions header file is written something like this:
#ifndef FUNCTIONS_HPP
#define FUNCTIONS_HPP
// some functions here
double random_double(){//some code}
#endif
this functions.hpp file is included only one in neuron.hpp and since ffnet is dependent on neuron, I included neuron.hpp in ffnet only once. This ffnet.hpp is included in main.cpp only once. main.cpp is file that I use for testing my library.
this linker throws error something like this:
/usr/bin/ld: /tmp/ccN7ywby.o: in function `maya::random_double()':
neuron.cpp:(.text+0x0): multiple definition of maya::random_double()'; /tmp/ccvDr1aG.o:main.cpp:(.text+0x0): first defined here
/usr/bin/ld: /tmp/cc66mBIr.o: in function `maya::random_double()':``
ffnet.cpp:(.text+0x0): multiple definition of `maya::random_double()'; /tmp/ccvDr1aG.o:main.cpp:(.text+0x0): first defined here
Also I compiled my program using :
g++ main.cpp neuron.cpp ffnet.cpp -o net
I don't think this will be needed but just in case :
$ uname -a
Linux brightprogrammer 4.19.0-kali3-amd64 #1 SMP Debian 4.19.20-1kali1 (2019-02-14) x86_64 GNU/Linux
You must write code of random_double() in .cpp file other than .hpp or .h file. Or, add inline before double random_double() { //some code } if you keep your code in your .hpp file.
The problem
You have your function definition with their full code in a header that you include in several compilation units. This causes the function to be defined in each compilation unit (cpp) and this breaks the One Definition Rule (ODR).
The include guards make sure that the same definition doesn't occur several time in the same compilation unit (e.g. if you include function.hpp in neuron.hpp and also include it directly). But here this header is included directly or indirectly in main.cpp, ffnet.cpp and neuron.cpp, which makes a first definition and 2 invalid redefinitions.
The solution
You must change function.hpp to keep only the function declaration:
#ifndef FUNCTIONS_HPP
#define FUNCTIONS_HPP
double random_double(); // no body !!
#endif
and move the function bodies to a separate function.cpp, which must be added to your compiler command.
The advantage of this approach are:
You can then compile the utility functions separately. Every time you'd change the function body, you'd no longer have to recompile all the cpp.
Encapsulation is improved, by sharing in the hpp only what other modules need to know, and hiding the implementation details.
Reuse could be facilitated across projects by making a library of functions.
The includes would be shorter (in case in some distant future your code would evolve to a large project with thousands of hpp, this could make you gain some time)
Additional remarks
Not sure that it applies, but be aware also that it's not a good idea to include a header into a namespace.
I also recommend reading this article about headers. It's old but the advice is still very relevant :-)
Note that there are exceptions to the ODR for classes and inline functions, in which case the multiple definitions must be exactly the same sequence of tokens.
I'm trying to deal with this problem for some time and I can't seem to find the solution. I'm getting error:
one or more multiply defined symbols found
I faced this error while dealing with something more complicated, but even simple examples like this one don't work for me. Here is my main.cpp:
#include "defs.cpp"
int main()
{
string a = "A";
printIt(a);
}
, and here is my defs.cpp:
#include "header.h"
void printIt(string a)
{
cout << a;
}
, and this is my header.h:
#include <string>
#include <iostream>
using namespace std;
void printIt(string a);
I guess this is something trivial, but please don't rage if you think this is duplicate, because I'm a beginner and I didn't understand more complicated examples. Some help would be appreciated.
When you see #include "defs.cpp" you need to get very suspicious: cpp files are not meant to be included; only header files are designed for that.
Instead of including a cpp file, write a header for it. It appears that you have a suitable header already - your header.h, which contains the forward declaration of printIt:
void printIt(string a);
Now replace #include defs.cpp with #include "header.h", and compile your code. This should fix the problem.
Compiling this depends on the system where you are trying it out. On UNIX-like systems, you would write
g++ defs.cpp main.cpp
./a.out
You should not #include a CPP file. Only include header files containing the function prototype definitions. If no such header file exists, put the function prototype in your program (for eg. in file where main is written).
In your case, you are including (directly/indirectly) the CPP file which is having the definition of the function. Since same definition is compiled through CPP files, compiler is putting them into .OBJ file (known as intermediate or object files). The linker finally attempts to combine these Object files, and says some function (symbol) is multiply defined.
In main.cpp you are including defs.cpp which includes a definition of printIt. So the translation unit corresponding to main.cpp defines printIt.
However, you are also compiling defs.cpp which defines printIt. defs.cpps corresponding translation unit thus defines printIt too.
Combining both into one program would lead to multiple (yet equivalent) definitions of this function which is forbidden by the ODR. Remove the #include directive and your program should link correctly.
This is because you are including:-
#include "defs.cpp"
and due to this there are multiple definitions of method printIt.
These are some basic rules:-
1) You must always include only header files in your source files. Even then you have to make sure header files are included only once because if it is included more than once then there could again be problem of multiple definition.To protect against that your header files should contain header gaurds.
2) C++ always adheres with single definition rule. However , you can have as many declaratons as possible as long as all declarations are consistent.
I am using an open source library, which provides a .hpp-file with several static functions defined that looks like the code below.
When I include this file twice in my project I always get a linker error that complains about duplicate symbols. I am well aware of the fact that the functions are being defined twice, but I do not know how to resolve this. I have tried marking the functions extern or inline without success.
What is the best way to resolve this?
#ifndef OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_
#define OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_
#include <algorithm>
#include <cmath>
#include <iterator>
#include <vector>
#include <limits>
#include <iostream>
#include "openMVG/robust_estimation/rand_sampling.hpp"
namespace openMVG {
namespace robust{
static double logcombi(size_t k, size_t n)
{...}
...
Edit: I forgot to say that there are also template functions, which means that I cannot use .h and .cpp files. So that is why they used .hpp files. On this page ( http://www.cplusplus.com/doc/tutorial/templates/ ) on the bottom it says that linkers should not produce errors in this case. I am using Xcode as an IDE with standard settings. Apparently there is something wrong here. The linker error looks like this:
duplicate symbol __ZN7openMVG6robust13UniformSampleEmmPSt6vectorImSaImEE in:
/Users/chris/Library/Developer/Xcode/DerivedData/SfM_OpenMVG-dgkssozpvorbpphdefdpurfpdaqv/Build/Intermediates/SfM_OpenMVG.build/Debug/SfM_incremental_unified.build/Objects-normal/x86_64/SfMIncrementalEngine.o
/Users/chris/Library/Developer/Xcode/DerivedData/SfM_OpenMVG-dgkssozpvorbpphdefdpurfpdaqv/Build/Intermediates/SfM_OpenMVG.build/Debug/SfM_incremental_unified.build/Objects-normal/x86_64/computeMatches.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Resolution: As it turns out the hpp-file I was referring to includes a file that defines a function with same name as one of the functions in the original file and that is what cause the linker error. I have no idea why this even worked in the first place when just including the .hpp file once.
I know you said you've done this but replace
static double logcombi(size_t k, size_t n)
with
inline double logcombi(size_t k, size_t n)
and fully recompile.
To distribute your library in a header is a very strange thing. Since you have access to the source code, I'd just create the corresponding cpp file, copy & paste the code from the header to the cpp file, and then remove the bodies of the functions in the header.
I'd also remove the static functions from the header: it actually does not make much sense to have a static (private) function in the file in which you expect to find the exportable symbols (i.e., public functions).
Finally, are you sure there are only functions in that hpp file? If there were constants it would be equally problematic. In that case I'd keep the declaration with an extern in the header and would move the constant to the cpp file.
I know, it is a lot of work (well, not so much, actually), but it is also the only sensible way to arrange things.
Hope this helps.
As far as I can see, you implement such functions in the same place you declare them. This is the cause of error on double inclusion. So far, you have two alternatives:
Employ "inline" clause as recommended by Bathsheba. The problem is: "inline" is just a hint. Compiler may refuse your attempts of inlining the functions, even if "forceinline" asked. It seems, your case is not inline-compatible as it not helps you.
Split a function as usual .H + .CPP pair, so that client code would include the .H file and then link with a lib containing the .CPP
The fact you name your file as .HPP instead of .H does nothing with the way how compiler treats it. You can use any arbitrary extension for a file and then include it as a header. So, naming convention here is no more than good programming style (.H for C/C++ compatible headers, .HPP for C++ only).
This question already has answers here:
linux gcc linker problems with C program
(3 answers)
Closed 10 years ago.
I have a .h file
test.h
std::list<std::string> RegisterList;
I want to access this list in 2 .c files
A.c
#include "test.h"
RegisterList.push_back(myString);
B.c
#include "test.h"
RegisterList.push_back(myString2);
When i compile this code, i get an error
ld: fatal: symbol `RegisteredList' is multiply-defined:
What can be the problem ? Is RegsiterList is initialized by default in test.h which is leading to this problem ?
Because you defined the object in the header file and violated one definition rule. Never define objects in header file.
If you want to use a global object, You need to declare it as extern and define it in one and only one source file.
You need something like:
test.h
extern std::list<std::string> RegisterList;
A.c
#include "test.h"
RegisterList.push_back(myString);
B.c
#include "test.h"
std::list<std::string> RegisterList;
RegisterList.push_back(myString2);
Your code goes through a chain: preprocessor -> compiler -> linker. Your problem originates with the preprocessor, but doesn't show up until the linker.
#include is a pre-processor directive.
Instead of compiling your .cpp file, the preprocessor synthesises another file from it, pasting in any included files.
The compiler then compiles the synthetic file producing an object file which contains data definitions, among other things.
You direct the preprocessor to #include the header file in two different .cpp files, which produces two different object files with the same data defined.
ld: fatal: symbol 'RegisteredList' is multiply-defined
This error message is the linker (ld) complaining that a global symbol is defined multiple times, and it doesn't know which one to use.
Don't instantiate the variable in a header file. Always instantiate it in a code file, and refer to the instantiation in a header file.
DebugUtil.h
#ifndef DEBUG_UTIL_H
#define DEBUG_UTIL_H
#include <windows.h>
int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
#endif
When I try to run this I get this error:
Terrain.obj : error LNK2005: "int
__cdecl DebugMessage(char const *)" (?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
Renderer.obj : error LNK2005: "int
__cdecl DebugMessage(char const *)" (?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
test.obj : error LNK2005: "int __cdecl
DebugMessage(char const *)"
(?DebugMessage##YAHPBD#Z) already
defined in Loodus.obj
C:\Users\Tiago\Desktop\Loodus
Engine\Debug\Loodus Engine.exe : fatal
error LNK1169: one or more multiply
defined symbols found
But why does this happen? I have #ifndef #define and #endif in the header so multiple definitions shouldn't happen
Put the definition (body) in a cpp file and leave only the declaration in a h file. Include guards operate only within one translation unit (aka source file), not across all your program.
The One Definition Rule of the C++ standard states that there shall appear exactly one definition of each non-inline function that is used in the program. So, another alternative would be to make your function inline.
Make the function inline or declare the function in a header file and define it in a cpp file.
inline int DebugMessage(const char* message)
{
const int MAX_CHARS = 1023;
static char s_buffer[MAX_CHARS+1];
return 0;
}
EDIT:
As a comment by Tomalak Geret'kal suggests, it's better to use my latter suggestions than my former and move the function's declaration to a cpp file.
(Assuming the posted code is a header, included from multiple .cpp files)
Header guards do not protect you from link-time multiple definitions. Regardless that you have ensured the header will only appear once per Translation Unit, if you have more than one Translation Unit then that's still multiple definitions.
Write definitions in source files, and only declarations in headers.
The only exceptions are inline functions, functions defined within a class definition (though this is not recommended!) and function templates.
This function is included into every translation unit and as a result you get multiple definitions of it - each .obj file contains its own copy. When it's time to link them all together the linker rightfully shows the above error.
You can do a few things:
Move the definition to a .cpp file and keep only the declaration in the header.
Use an anonymous namespace around the function in your header file (but realize it's a hack - you will still have multiple definitions, just no name collision).
Mark it as inline (although it might not always work - only if the compiler actually chooses to inline it). That's also a hack for the same reason as above.
That only prevents multiple inclusions in the same source file; multiple source files #includeing it will still generate multiple definitions of DebugMessage(). In general, you should either not place functions in header files at all or make them static (and usually inline, since otherwise it doesn't usually make sense to have multiple static definitions of the same function).
100% Certain you correctly included Guards but still getting redefinition error?
For Visual Studio:
I was really frustrated because I was correctly included guards,
only to find out the problem was visual studio. If you have added the file
to your project, the compiler will add the file twice even if you have
include guards around your implementation file and header file.
If you don't use visual studio exclusively, and say... use code::blocks sometimes, you might want to only #include the file when you detect the absence of the visual studio environment.
DebugUtil.h :
----------------------
#ifndef _WIN32
#include "DebugUtil.c"
#endif
----------------------
If you are okay with including stdio.h,
you can be a little less hackish about it:
DebugUtil.h :
----------------------
#include <stdio.h>
#ifdef _MSC_VER
#include "DebugUtil.c"
#endif
----------------------
Reference:
Predefined Macros, Visual Studio:
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
Move the definition to a .cpp file.
Declare your functions in C++ files. Since you defined your function in the header file, and that header file is included from multiple source files, it gets defined for each source file that includes it. That's why it's reported as being defined in multiple places.
Alternatively, you could make it inline so that the code is inserted wherever it's used instead of being defined as a separate function each time.
It looks like you are including DebugUtil.h in more than one translation unit, then linking those objects together. However, DebugUtil.h provides a definition for the DebugMessage function, so that definition exists in all of the translation units that incorporated the header. As a result, when you link the objects, the linker rightly complains that the symbol is multiply defined.
Change DebugUtil.h so that it declares DebugMessage via a prototype, but does not provide a definition, and place the definition of DebugMessage in a .c file which you will compile and link with your other objects.