C++ linker error with static functions in .hpp-file - c++

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

Related

one or more multiply defined symbols found error - simple

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.

difference in including header in .cpp and .h

I have a code in which I #include<linux/videodev2.h>. There are three files:
one header file- includes: stdint.h and stdlib.h. Defines a couple of functions, a struct, say abc, and some #define macros. One of the functions is
int func(int, uint32_t, size_t, abc*);
one cpp file with a lot of methods, including definition of the functions in the .h file.
one main.cpp which has main() which has a function call to the method in the .h file (complete file below). This file is only for testing purposes.
#include "head.h"
int main() {
func(5, (uint32_t)5, (size_t)5, 0);
return 0;
}
What is see is a curious case:
If I include linux/videodev2.h only in .h file, uint32_t and other things defined in this header are not accessible by the .cpp files. (erros I get are: uint32_t was not declared in this scope, and uint32_t does not name a type, among others). This happens even if the first line of the .h file is #include<linux/videodev2.h>
If I include the videodev2 header in both the cpp files, it works only if I import it (videodev2) before the .h file.
If I use func(5, (uint32_t)5, (size_t)5, (abc*)0); in the main.cpp file, I get the error that abc is not declared in this scope.
I am compiling using the command: g++ main.cpp head.cpp
I am unable to figure out why is this. I would like to include the videodev2 header in the .h file since, it is almost certain that the code using the .h file will be dependent on it. But it seems that including it in .h file has no effect at all.
I must be honest here. This was C code which I had to convert to C++. I know that I am not conforming to the best practices and standards. But why is this behaviour seen?
Remember that the #include directive indicates to the preprocessor the contents of the specified file should be treated as if they appeared directly in the source file in place of the directive (paraphrased from MSDN).
With that in mind, it seems like you are encountering improper order of #includes and also missing #includes. My guess would be that you are not including your own header file in your .cpp files. This would explain cases one and three. Consider the following files:
// header.h
// #include <linux/videodev2.h> <-- Option 1
class A {
void func(uint32_t var);
};
// header.cpp
void A::func(uint32_t var) {
// implementation
}
// main.cpp
// #include <linux/videodev2.h> <-- Option 2
#include "header.h"
// #include <linux/videodev2.h> <-- Option 3
int main() {
// implementation; something creates an instance of A and calls func
}
Now, Option 1 is not exactly desirable; it's good practice to avoid #includes in header files because they can increase build times and create unwanted dependencies. However, it will ensure that the types header.h requires are there for it to use. The essential bit is that the contents of linux/videodev2.h have to appear before the contents of header.h, anywhere that header.h is #included.
This brings me to Option 2. Option 2 will also compile correctly, because linux/videodev2.h is included before your header, and your header relies on types defined in it. Also important is that both main.cpp and header.cpp must #include "header.h", because they reference symbols declared in it.
If you were to go with Option 3, you would get compilation errors that the type uint32_t is not defined, and the compiler would point to your header file. This is because the contents of the header file appear before the contents of linux/videodev2.h, and so the compiler does not yet understand what the type uint32_t is when it encounters it.
So, given all that, you have choices: include `linux/videodev2.h' before each include of your own header file, or include it directly in your header file. I mentioned earlier that the latter is not good practice, but for your particular case, it might be the better option of the two, in case your header file needs to be included in many .cpps.
I think this would be a good opportunity to dive into precompiled headers, but I'm not as well-versed in them, so I'd leave it to someone who has more experience to explain them.
Hope this helps :)
Found the answer. There was .h.gch file in the directory. I didn't know about precompiled header. Thanks ktodisco for the insight. I still have no idea why that file was there in the first place.

dealing with includes and using headers

I have "Hello World" code that uses function fhi from another hi.cpp file that has it's header.
Correct my if my understanding is wrong according following:
I can do include cpp file like #include "c:\c\hi.cpp" instead of using header without any problems except that fact that it looks more readable in header file.
If I include header like sample in my main program hi.h, must hi.h include hi.cpp, or it is done automatically according the same file name hi. I'm wondering how compiler knows where is function fhi body.
Is it possible to have different names for header and cpp files?
Programm:
#include "stdafx.h"
#include "c:\c\hi.h"
int _tmain(int argc, _TCHAR* argv[])
{
fhi(1);
return 0;
}
hi.h
#include <cstdlib>
#include <iostream>
int var;
int fhi(int f);
hi.cpp
#include <cstdlib>
#include <iostream>
int fhi(int f)
{
return 0;
}
must hi.h include hi.cpp
No. hi.h contains only declarations, that can be other by other .cpp files.
I'm wondering how compiler knows where is function fhi body.
It doesn't. You need to compile all *.cpp files into the object files. In your case, you will have two object files: program.o and hi.o. The linker can now take these two object files, and spit out the executable. References to other functions(in this case the actual definition of fhi(..)) is resolved in this stage.
Also why are you using absolute paths in #includes? It will break when you move the "c" directory around.
What normally happens is that the build system compiles the .cpp files into object files, that then are used to build the main executable. The means to tell this to the build system vary greatly.
One important point is that your hi.cpp must include hi.h. You should also put an include guard in hi.h, to make it safe to be included more than once in a translation unit.
I can do include cpp file like #include "c:\c\hi.cpp" instead of using
header without any problems except that fact that it looks more
readable in header file.
yes, you can do so but it is not recommended, one of the problems is encapsulation; you are not hiding implementation details. readability as you mention is also a concern, a header is easier to read since it clearly shows what methods are public.
If I include header like sample in my main program hi.h, must hi.h
include hi.cpp, or it is done automatically according the same file
name hi. I'm wondering how compiler knows where is function fhi body.
the header needs to be explicitly included in hi.cpp and any .cpp file that use the class defined in the header.
Is it possible to have different names for header and cpp files?
yes but it is not recommended, it makes it more difficult to find things.
as a general rule: think about that other programmers may want to look in your code so you need to structure it so that it is easy to read and understand as well as making it easier for you 2 years down the road to remember where things are.
In Visual Studio all CPP files included in the project will be compiled to produce OBJ files. These OBJ files will be linked together to form the EXE or DLL.
Including files are similar to pasting the contents of the file at that location. The only difference is that this pasting is done by the pre-compiler during compilation.
Finding out where a function body resides is done by the either the compiler if the function is inline or by the linker when the final binary is created.
First, if the header file is in the same directory as the source file including it, you can use just
#include "hi.h"
In other words, you don't have to use a full path. (See e.g. the inclusion of "stdafx.h".)
Second, in your header file you don't need to include other header files, unless you need types from those. In your header file you don't have anything that needed from the header files you include.
Third, you should protect header files header files from being included more than once in the same source file, this can be done with a so called include guard, on in some compiler via a special directive called #pragma once.
Fourth, in your header file you define a global variable var. This variable will then be defined in every source file you include the header file in, which will lead to errors. You need to declare the variable as extern:
extern int var;
Then in one source file you define the variable like you do now.
Fifth, you should never include source files in header file (with some special exceptions that you don't have to think about yet). Instead you add all source files to the project (I assume you are in MS VisualStudio) and it they will all be built and linked together automatically.
Sixth, since you seem to be using VisualC++, then you are probably using something called precompiled headers. This is something the compiler uses to speed up compilation. However, for this to work you have to include "stdafx.h" in all source files. That include actually has to be the first non-comment line in each source file.

Does putting a whole class definition in a ".h" make the executable larger?

We define a C++ class in a .h and define its methods in a .cpp, but it makes the code look less organized.
I want to put all method's definition in the class definition which is in a .h file, but I'm worrying that the compiler generate duplicated code for the same methods/functions when one class header file is included by different files.
Does the linker find out and merge the duplicated code pieces to reduce the file size?
If not, is it better to use .hpp instead? I heard that a .hpp is for this.
And it does make minor difference when I just change a .h file for a .hpp (I don't know why), compiled with G++.
Yes. It may create larger executable and that is because the member functions which are defined in the class itself, are inline by default, whether you mention the keyword inline in the defintion or not. Usually, inline function causes larger executable because the compiler will define it multiple times wherever it is called from.
.h vs .hpp is the 90% equivalence of
#include <cmath> vs #include <math.h>
Some people prefer to use .hpp when they are doing exclusive C++ programming. You will see .hpp in libraries like Boost.
However, the other 10% is really important. For example, taking from Boost library doc, they explain the reason of using .hpp over .h:
Most Boost libraries are header-only: they consist entirely of header
files containing templates and inline functions, and require no
separately-compiled library binaries or special treatment when
linking.
If you fall in that case, you should use .hpp, but this can cost longer compilation time. Otherwise, you might want to keep .h style. That's just my personal taste. It isn't C-oriented at all, in my honest opinion.
Further reading:
Splitting templated C++ classes into .hpp/.cpp files--is it possible?
Condensing Declaration and Implementation into an HPP file
C++ templates declare in .h, define in .hpp
You have nothing to worry about. It makes absolutely no difference how it's broken up, it's what your files describe that makes it bigger, not how that description is spread out.
.h or .hpp makes no difference as well.
To answer your question about a larger executable, yes it will make your executable larger. When a you #include a header file in a source or header file, the preprocessor replaces the #include with the contents of the header file. This is why it is necessary to protect your header files with the following header protection:
#ifndef HDR_H
#define HDR_H
...
#endif
However, you will get linker errors if you include the header file (that has function definitions) in multiple files that are part of the same executable. It would wise for you to split class and function definitions and declarations into .cpp and .hpp files, respectively. This will greatly reduce the amount of linker headaches.
Also, .h = .hpp. Doesn't matter which one you choose. Personal preference...
There's all you need here: Header files, pros and cons of putting all you code in them. Hope it helps!
Using header files results in quicker compile time and smaller executable. It also looks considerably cleaner because you can get a quick overview of your class by looking at its .h declaration.

How do C++ header files work?

When I include some function from a header file in a C++ program, does the entire header file code get copied to the final executable or only the machine code for the specific function is generated. For example, if I call std::sort from the <algorithm> header in C++, is the machine code generated only for the sort() function or for the entire <algorithm> header file.
I think that a similar question exists somewhere on Stack Overflow, but I have tried my best to find it (I glanced over it once, but lost the link). If you can point me to that, it would be wonderful.
You're mixing two distinct issues here:
Header files, handled by the preprocessor
Selective linking of code by the C++ linker
Header files
These are simply copied verbatim by the preprocessor into the place that includes them. All the code of algorithm is copied into the .cpp file when you #include <algorithm>.
Selective linking
Most modern linkers won't link in functions that aren't getting called in your application. I.e. write a function foo and never call it - its code won't get into the executable. So if you #include <algorithm> and only use sort here's what happens:
The preprocessor shoves the whole algorithm file into your source file
You call only sort
The linked analyzes this and only adds the source of sort (and functions it calls, if any) to the executable. The other algorithms' code isn't getting added
That said, C++ templates complicate the matter a bit further. It's a complex issue to explain here, but in a nutshell - templates get expanded by the compiler for all the types that you're actually using. So if have a vector of int and a vector of string, the compiler will generate two copies of the whole code for the vector class in your code. Since you are using it (otherwise the compiler wouldn't generate it), the linker also places it into the executable.
In fact, the entire file is copied into .cpp file, and it depends on compiler/linker, if it picks up only 'needed' functions, or all of them.
In general, simplified summary:
debug configuration means compiling in all of non-template functions,
release configuration strips all unneeded functions.
Plus it depends on attributes -> function declared for export will be never stripped.
On the other side, template function variants are 'generated' when used, so only the ones you explicitly use are compiled in.
EDIT: header file code isn't generated, but in most cases hand-written.
If you #include a header file in your source code, it acts as if the text in that header was written in place of the #include preprocessor directive.
Generally headers contain declarations, i.e. information about what's inside a library. This way the compiler allows you to call things for which the code exists outside the current compilation unit (e.g. the .cpp file you are including the header from). When the program is linked into an executable that you can run, the linker decides what to include, usually based on what your program actually uses. Libraries may also be linked dynamically, meaning that the executable file does not actually include the library code but the library is linked at runtime.
It depends on the compiler. Most compilers today do flow analysis to prune out uncalled functions. http://en.wikipedia.org/wiki/Data-flow_analysis