Using non-template functions in template classes - c++

I have a task:
To implement a template vector class (let's name it myvector). I need to use this class in multiple files in my project, so I've put it's declarations in "myvector.h" file, and implementation into "myvector.hpp" file, and then included "myvector.hpp" in "myvector.h" after all the declarations (as described there). However, I have one non-template function in "myvector.hpp". So when I include "myvector.h" file in main file, everything works fine. But when I include "myvector.h" in another one file ("bignum.cpp"), I get a linker error:
error LNK2005: "unsigned int __cdecl gerasimov_dmitry::calculate_capacity(unsigned int)" (?calculate_capacity#gerasimov_dmitry##YAII#Z) already defined in bignum.obj
I understand the causes - "bignum.h" code gets included both in main.cpp and in bignum.cpp file, so compiler doesn't know which one "calculate_capacity" function to use. So, my question is how to fix this situation.

You have to declare the function inline (or alternatively move the definition to a single translation unit).
The problem that you are facing is that if you define the function in the header, and include that header in more than one translation unit, the compiler will generate the function in all translation units.
When the linker tries to generate the program (or library) it finds that the function is defined multiple times and complains about it, as that is a violation of the ODR (One Definition Rule). By marking the function as inline the compiler will flag that function so that when the linker sees the multiple definitions instead of choking it will discard all but one of the definitions.

Related

Why are C++ header functions put in a seperate file?

I'm working my way through a C++ tutorial, and in one of the articles on the preprocessor/header files the author creates 2 'header files' (not the technical term, of course), example.h and example.cpp. In example.h he puts the forward declarations for the functions and the header guard, and in example.cpp the actual body of the functions. Why is this? I tried putting the body of the function in the example.h file and it worked just fine, so why does he put it separately? Is it customary, or does it pose problems in bigger problems? Or what?
Can someone please enlighten me on this...
C++ has a rule called the one-definition rule that says that every function needs to be defined once and only once (there are a few exceptions to this rule, but we'll ignore them for now.) The function prototype typically included in a header file is a declaration saying that the function exists, and the implementation in the .cpp file is the definition giving the code for the function.
If you put the definition of the function in a header file and then include the header file in multiple places, you'll get linker errors because you're breaking the one definition rule - each .cpp file that's compiled will have its own copy of the definition of the function. On the other hand, if you just put the declaration in the header and then put the definition in a single source file, then there's only one definition and nothing will break.
There are a few exceptions for the one definition rule. First, all inline functions are exempt from ODR, so you could potentially put function definitions in a header file if you mark all the functions inline, though this is generally not considered a good idea for all but the smallest functions. Second, template functions are exempt from the ODR, which (among other things) is one of the reasons you see template functions defined in headers.
Put the function body in example.h. Then, when you write a second .cpp file that also includes example.h, and link it with example.cpp, then you'll get a linker error. The linker will see 2 definitions of the function in example.h.
Becouse in the header file you only declare functions that is really important when you want to use a custom linking configuration. For example if a function is defined in a file object and is used in an another object the linker must have the same reference for this function to link the two different files.

Adding more code makes code uncompileable

I have a header file which begins with
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
then some code followed by
#endif
The code contains only function declarations, some include of other header files and the a few template functions. However, the problem occurs when I add one single line of code. I get linker error that the function I added has already been defined in an object file. I'm using Visual Studio 2012 Premium as compiler. I have tried to remove any existing function from the header file, and that also goes through the compiler. On the other hand, if I add any new line that may be new to the compiler, it refuses to compile saying it has already been defined. Does anyone have any clue what might be wrong or can I have stumbled upon an error inside the compiler itself? (which I highly doubt)
Edit:
The solution was to declare the function the the header file, but to define it in the CPP file. But the real issue was that when I include a header file for returning an object of the type declared in the header file, it does not compile. It many of the errors "Missing ; in front of *" which was types declared in other header files.
Although you haven't shown use any code or error messages, I'm guessing that there are function definitions (including the code for the function body), not just declarations, in the header.
These must either be declared inline, which allows them to be defined in more than one translation unit; or moved into a single source file, leaving just the declaration in the header, so they are only defined on one translation unit.
The "One Definition Rule" says that (unless they are inline) functions may only have one definition in the program.
Also, your include guard shouldn't begin with an underscore, nor contain a double underscore; names like that are reserved.
Adding non-inlined function definitions to header files is generally bad. The compiler will generate code for the function in every file it is included in resulting in the redefintion error you are encountering. Instead you should declare the function in the header and place the definition in a source file (.cpp).
Global.h
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
void somefunction(); // <-- declaring the function.
#endif
SomeSource.cpp
#include "Global.h"
// Here is where define the function
void somefunction()
{
}

Include guards not working? (500 errors of type LNK2005 x already defined in y.obj)

I have a big project (400 files) and all of the headers have include guards and everything, however I get 500 LNK2005 errors.
Could it be that I have function bodies defined in some headers? Cause I saw the same things in the DirectX utility headers(DirectXCollision has some of it's functions are completely in the header).
Or could it be because they are using .inl files instead of .cpp?
Could it be that I have function bodies defined in some headers?
Yes, that could be. Defining a function in more than one translation unit results in a duplicated symbol definition error.
You can get around the duplication error by declaring those functions inline. [7.1.2]/2 reads:
A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.
Include guards will only save you from including the same header multiple times into the same compilation unit (one cpp file). If you include the header into a second cpp file and then link them together, both of them will have anything the header brings in. That's why it is usually a bad idea to have function implementations in the headers.
You can work around that by declaring your function inline, then compiler will copy/paste them around.
Do you define global variables in your header files? That can be a cause of the error.
And include guards will not help.
A global variable should be defined only in one translation unit and should be externed in all other translational unit.
For eg.
in x.h, you have
int myVar;
Now you #include x.h in both a.cpp & b.cpp,
then you will get a linker error even if you had include guards in x.h
Because now myVar will get defined in both a.obj and b.obj and the linker will find 2 myVars.

C++ including a ".h" file, function duplication confusion

I'm currently writing a program, and couldn't figure out why I got an error (note: I already fixed it, I'm curious about WHY the error was there and what this implies about including .h files).
Basically, my program was structured as follows:
The current file I'm working with, I'll call Current.cc (which is an implementation of Current.h).
Current.cc included a header file, named CalledByCurrent.h (which has an associated implementation called CalledByCurrent.cc). CalledByCurrent.h contains a class definition.
There was a non-class function defined in CalledByCurrent.cc called thisFunction(). thisFunction() was not declared in CalledByCurrent.h since it was not actually a member function of the class (just a little helper function). In Current.cc, I needed to use this function, so I just redefined thisFunction() at the top of Current.cc. However, when I did this, I got an error saying that the function was duplicated. Why is this, when myFunction() wasn't even declared in CalledByCurrent.h?
Thus, I just removed the function from Current.cc, now assuming that Current.cc had access to thisFunction() from CalledByCurrent.cc. However, when I did this, I found that Current.cc did not know what function I was talking about. What the heck? I then copied the function definition for thisFunction() to the top of my CalledByCurrent.h file and this resolved the problem. Could you help me understand this behavior? Particularly, why would it think there was a duplicate, yet it didn't know how to use the original?
p.s - I apologize for how confusing this post is. Please let me know if there's anything I can clear up.
You are getting multiple definitions from the linker - it sees two functions with the same name and complains. For example:
// a.cpp
void f() {}
// b.cpp
void f() {}
then
g++ a.cpp b.cpp
gives:
C:\Users\neilb\Temp\ccZU9pkv.o:b.cpp:(.text+0x0): multiple definition of `f()'
The way round this is to either put the definition in only one .cpp file, or to declare one or both of the functions as static:
// b.cpp
static void f() {}
You can't have two global functions with the same name (even in 2 different translation units). To avoid getting the linker error define the function as static so that it is not visible outside the translation unit.
EDIT
You can use the function in the other .cpp file by using extern keyword. See this example:
//Test.cpp
void myfunc()
{
}
//Main.cpp
extern void myfunc();
int main()
{
myfunc();
}
It will call myfunc() defined in test.cpp.
The header file inclusion mechanism should be tolerant to duplicate header file inclusions.
That's because whenever you simply declare a function it's considered in extern (global) scope (whether you declare it in a header file or not). Linker will have multiple implementation for the same function signature.
If those functions are truely helper functions then, declare them as;
static void thisFunction();
Other way, if you are using the same function as helper then, simply declare it in a common header file, say:
//CalledByCurrent.h (is included in both .cc files)
void thisFunction();
And implement thisFunction() in either of the .cc files. This should solve the problem properly.
Here are some ideas:
You didn't put a header include guard in your header file. If it's being included twice, you might get this sort of error.
The function's prototype (at the top) doesn't match its signature 100%.
You put the body of the function in the header file.
You have two functions of the same signature in two different source files, but they aren't marked static.
If you are using gcc (you didn't say what compiler you're using), you can use the -E switch to view the preprocessor output. This includes expanding all #defines and including all #includes.
Each time something is expanded, it tells you what file and line it was in. Using this you can see where thisFunction() is defined.
There are 2 distinct errors coming from 2 different phases of the build.
In the first case where you have a duplicate, the COMPILER is happy, but the LINKER is complaining because when it picks up all the function definitions across the different source files it notices 2 are named the same. As the other answers state, you can use the static keyword or use a common definition.
In the second case where you see your function not declared in this scope, its because the COMPILER is complaining because each file needs to know about what functions it can use.
Compiling happens before Linking, so the COMPILER cannot know ahead of time whether or not the LINKER will find a matching function, thats why you use declarations to notify the COMPILER that a definition will be found by the LINKER later on.
As you can see, your 2 errors are not contradictory, they are the result of 2 separate processes in the build that have a particular order.

strange redefined symbols

I included this header into one of my own: http://codepad.org/lgJ6KM6b
When I compiled I started getting errors like this:
CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::reset_plot()':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105: multiple definition of `Gnuplot::reset_plot()'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:962: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)':
project/gnuplot-cpp/gnuplot_i.hpp:1041: multiple definition of `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:1041: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o:/usr/include/eigen2/Eigen/src/Core/arch/SSE/PacketMath.h:41: multiple definition of `Gnuplot::m_sGNUPlotFileName'
I know it's hard to see in this mess, but look at where the redefinitions are taking place. They take place in files like /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105. How is the new operator getting information about a gnuplot header? I can't even edit that file. How could that ever even be possible? I'm not even sure how to start debugging this. I hope I've provided enough information. I wasn't able to reproduce this in a small project. I mostly just looking for tips on how to find out why this is happening, and how to track it down.
Thanks.
You're obviously violating the "one definition rule". You have lots of definitions in your header file. Some of them are classes or class templates (which is fine), some of them are inline functions or function templates (which is also fine) and some of them are "normal" functions and static members of non-templates (which is not fine).
class foo; // declaration of foo
class foo { // definition of foo
static int x; // declaration of foo::x
};
int foo::x; // definition of foo::x
void bar(); // declaration
void bar() {} // definition
The one definition rule says that your program shall contain at most one definition of an entity. The exceptions are classes, inline functions, function templates, static members of class templates (I probably forgot something). For those entities multiple definitions may exist as long as no two definitions of the same entity are in the same translation unit. So, including this header file into more than one translation unit leads to multiple definitions.
Looks like you include conflicting headers. Try to check your include paths. They usually are defined in -I directive (at least in gcc) or in an environment variable.
Reading compiler errors usually helps. You should learn to understand what the compiler is telling you. The fact that it is complaining about a symbol being redefine is saying that you are breaking the One Definition Rule. Then it even tells you what the symbols are:
class GnuPlot {
//...
GnuPlot& reset_plot(); // <-- declaration
//...
};
//...
Gnuplot& Gnuplot::reset_plot() { // <-- Definition
nplots = 0;
return *this;
}
You can declare a symbol as many times as you wish within a program, but you can only define it once (unless it is inlined). In this case the reset_plot is compiled and defined in all translation units that include the header, violating the One Definition Rule.
The simplest way out of it is declaring it inline, so that it can appear in more than one compilation unit and let the linker remove the redundant copies (if any) later on.
A little more problematic are the static members that must be declared within the class and defined (only once) in a translation unit. For that you can either create a .cpp file to define those variables (and any function/method that you don't need inlined in the header).