Linker errors - undefined references - c++

Yes, I know this has been asked a billion times before, I've checked at least 100 duplicates of this question, and still haven't found an answer.
I'm getting undefined reference errors to all of my LList functions, although it all seems to be properly defined and linked. Since my code is a bit too long to paste here, I made a pastie: Click
I compile my code with: g++ driver.cpp box.cpp LList.cpp Song.cpp Album.cpp -o driver

A class or function template is not a class or function and hence cannot be placed in a .cpp file like classes or functions. Rather, a template is a blueprint for how to make a class or function, namely a particular instantination of the template.
You can solve your problem in two ways:
1 either put all the templated code in the respective header files.
2 or instantinate the code explicitly in the .cpp files. For example
// Llist.cpp
#include Llist.hpp
#include Sonc.hpp
/* definition of members of Llist<> */
template class Llist<Song>; // creates class Llist<Song>
Solution 1 always works, but has the potential for HUGE header files and exposes all (or most) implementation details to the user. Solution 2 avoids huge headers and hides implementation details, but requires that you know which instantination you actually need (often impossible, in particular for such general concepts as linked lists).
Finally, solution 3: use the C++ standard library (std::list, std::forward_list) and don't worry.

Template classes and functions must be defined inline. Thats the problem. For example:
//box.h
#ifndef BOX_H
#define BOX_H
template <typename DataType>
struct box
{
DataType data;
box<DataType> *next;
box(DataType d, box<DataType>* n)
{
data = d;
next = n;
}
};
#endif
And remove the .cpp file; you should do the same to the LList.h/cpp

Related

Is it bad practice to include a .cpp file when your implementation file is a templated class?

I have a template class that I want to separate from my main.cpp file, where I'll be conducting tests, etc. The problem I have is that there's no easy way to separate the template class into .h/.cpp files because the compiler needs to know which type(s) the object may potentially be.
I came across this resource and I'm primarily looking at "Method 2." Is it bad practice to include a .cpp file in the file that holds main?
I've always been told that it was generally unadvised, but what would be the best solution here?
Yes, it's bad practice.
It's also bad practice to include it in the corresponding header.
What if someone tries to compile the project by giving all .cpp files as input to the compiler?
Good practice would be to mark those special files with a special extension, usually .inl.
Best: let the class template implementation be part of the header.
Then you have
MyClass.hpp
Only separate the implementation out as a distinct file if there ever will be a need for the header's code without the implementation code.
Because if the code sans implementation will not ever be needed, there is no rationale for using a distinct file.
However. if you separate the implementation as a distinct file, make that a header too, because that's how it's intended to be used. It's not intended to be separately compiled. And you don't want some too smart IDE to do that.
Then, because headers should be self-contained, the implementation should include the purely declarative header, like this:
MyClass.fwd.hpp
Pure declarations.
MyClass.hpp
Includes the above pure header.
This then is structured very much like the standard library's <ioswfd>, which corresponds to MyClass.fwd.hpp above.
Why not #include the .cpp into the corresponding .h? This will solve the template compilation problem and at the same time follow the standard approach with non-templated classes.
SomeClass.h:
#ifndef SOMECLASS_H
#define SOMECLASS_H
template<class T>
class SomeClass { /* ... */ };
#include "SomeClass.cpp"
#endif
SomeClass.cpp:
template<class T> SomeClass::foo()
/*...*/
main.cpp:
#include "SomeClass.h"
int main() {
/* ... */
}
Just don't forget that you do not need to actually compile your SomeClass.cpp. As suggested by others, you might choose a different extension (not .cpp) for the implementation file.
UPD: on reading the article you linked, I see that this is called "Method 3".

How to find duplicate definitions from template specializations?

I have a template class with a specialization, defined in another file. Therefore it is possible to generate two versions of the same class: one time by replacing the template parameter and one time using the specialization. My current understanding is, that this can lead to two instanciations of the same type to have different sizes in memory, resulting in segmentation faults.
I created a minimal example and the following code is to illustrate the question:
Create a template class:
// - templateexample.h ---------------
#ifndef TEMPLATEEXAMPLE_H
#define TEMPLATEEXAMPLE_H
template<typename T> class Example
{
public:
Example(){}
int doWork() {return 42;}
};
#endif
// -----------------------------------
Template specialization in another file:
// - templatespecialization.h --------
#ifndef TEMPLATESPECIALIZATION_H
#define TEMPLATESPECIALIZATION_H
#include "templateexample.h"
template<> class Example<int>
{
public:
Example() : a(0), b(1), c(2), d(3) {}
int doWork() {return a+b+c+d;}
private:
int a; //<== the specialized object will be larger in memory
int b;
int c;
int d;
};
#endif
// --------------------------------
Have a class which includes only the template class definition, but should include the specialization.
// - a.h --------------------------
#ifndef A_H
#define A_H
#include "templateexample.h"
class A
{
public:
Example<int> returnSmallExample();
};
#endif
// - a.cpp ------------------------
#include "a.h"
Example<int> A::returnSmallExample() {return Example<int>();}
// --------------------------------
The main class now knows two versions of Example<int> the one from A and the one from the templatespecialization.h.
// - main.cpp ---------------------
#include <iostream>
#include "a.h"
#include "templatespecialization.h"
int main()
{
A a;
Example<int> test = a.returnSmallExample();
std::cout<<test.doWork()<<std::endl;
}
// --------------------------------
Please note, this problem will only occur when compiling class A separately, this example from ideone outputs 6, whereas using separate files can result in a segmentation fauls, or output 42 (https://ideone.com/3RTzlC). On my machine the example compiles successfully and outputs 2013265920:
In the production version of the above example everything is build into a shared library which is used by main.
Question 1: Why doesn't the linker detect this problem? This should be easy to spot by comparing the size of objects.
Question 2: is there a way to examine the object files or the shared library to detect multiple implementations of the same type like in the example above?
Edit: please note: the code above is a minimal example to explain the problem. The reason for the situation is that the template class is from one library and I cannot edit the files from this library. Finally the whole thing is used all over the place in the executable and now I need to find out if the problem above occurs.
Edit: code above can be compiled like this:
#!/bin/bash
g++ -g -c a.cpp
g++ -g -c main.cpp
g++ -o test a.o main.o
You have different definition of the same template and its specializations in different translation units. This leads to One Definition Rule violation.
A fix would be to put the specialization in the same header file where the primary class template is defined.
Question 1: Why doesn't the linker detect this problem? This should be easy to spot by comparing the size of objects.
Different types may have the same size (e.g. double and int64_t), so, obviously, just comparing sizes of objects does not work.
Question 2: is there a way to examine the object files or the shared library to detect multiple implementations of the same type like in the example above?
You should use gold linker for linking your C++ applications, if you do not use it already. One nice feature of it is --detect-odr-violations command line switch which does exactly what you ask:
gold uses a heuristic to find potential ODR violations: if the same symbol is seen defined in two different input files, and the two symbols have different sizes, then gold looks at the debugging information in the input objects. If the debugging information suggests that the symbols were defined in different source files, gold reports a potential ODR violation. This approach has both false negatives and false positives. However, it is reasonably reliable at detecting problems when linking unoptimized code. It is much easier to find these problems at link time than to debug cases where the wrong symbol.
See Enforcing One Definition Rule for more details.
Question 1: Why doesn't the linker detect this problem? This should be easy to spot by comparing the size of objects.
Because this is not a linker's problem. In case of templates, the main declaration and all the other specializations (be it class or function) should be visible upfront.
Question 2: is there a way to examine the object files or the shared library to detect multiple implementations of the same type
like in the example above?
At least I am not aware of any.
To further simplify this situation, look at a similar broken code:
// foo.h
inline void foo () {
#ifdef FOO
return;
#else
throw 0;
#endif
}
// foo1.cpp
#define FOO
#include"foo.h"
// ... uses foo() with "return"
// foo2.cpp
#include"foo.h"
// ... uses foo() with "throw"
It's possible that you get different results based on the way of compilation being used.
Update:
Having multiple body definitions for a same function is undefined behavior. That's the reason why you are getting an awkward output like 2013265920 and the same happens in my machine as well. The output should be either 42 or 6. I gave you above example because with inline functions you can create such race conditions.
With my limited knowledge on linking stage, the responsibility undertaken by a typical linker is limited only till rejecting more than 1 non-inline functions definitions with the same signature. e.g.
// Header.h is included in multiple .cpp files
void foo () {} // rejected due to multiple definitions
inline void bar () {} // ok because `inline` keyword is found
Beyond that it doesn't check if the function body is similar or not, because that is already parsed during earlier stage and linker doesn't parse the function body.
Having said above, now pay attention to this statement:
template functions are always inline by nature
Hence linker may not get a chance to reject them.
The safest way is to #include the read-only header into your specialized header and include that specialized header everywhere.
I don't know of a way to do this by analysis of the compiled binary, but you could build a graph of your program's #include relationships — there are tools that can do this, such as Doxygen — and use it to look for files that (directly or indirectly) include the library header but not the specialization header.
You'd need to examine each file to determine whether it actually uses the template in question, but at least you can narrow down the set of files that you have to examine.
I think you managed to deceive the compiler. But I should note that in my humble opinion you understand conception of templates in a wrong way, particularly you are trying to mix up template specialization with inheritance.
I mean, template specialization must not add data members to class, the only aims are to define types for function parameters and class fields. If you want to change algorithms, i.e. rewrite code, or add new date members to class, you should define derived class.
Concerning "several-step" separate compilation and template class in library, C++ reference said (http://www.cplusplus.com/doc/oldtutorial/templates/):
Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as its declaration. That means that we cannot separate the interface in a separate header file, and that we must include both interface and implementation in any file that uses the templates.
Since no code is generated until a template is instantiated when required, compilers are prepared to allow the inclusion more than once of the same template file with both declarations and definitions in a project without generating linkage errors.

Separating C++ Class Code into Multiple Files, what are the rules?

Thinking Time - Why do you want to split your file anyway?
As the title suggests, the end problem I have is multiple definition linker errors. I have actually fixed the problem, but I haven't fixed the problem in the correct way. Before starting I want to discuss the reasons for splitting a class file into multiple files. I have tried to put all the possible scenarios here - if I missed any, please remind me and I can make changes. Hopefully the following are correct:
Reason 1 To save space:
You have a file containing the declaration of a class with all class members. You place #include guards around this file (or #pragma once) to ensure no conflicts arise if you #include the file in two different header files which are then included in a source file. You compile a separate source file with the implementation of any methods declared in this class, as it offloads many lines of code from your source file, which cleans things up a bit and introduces some order to your program.
Example: As you can see, the below example could be improved by splitting the implementation of the class methods into a different file. (A .cpp file)
// my_class.hpp
#pragma once
class my_class
{
public:
void my_function()
{
// LOTS OF CODE
// CONFUSING TO DEBUG
// LOTS OF CODE
// DISORGANIZED AND DISTRACTING
// LOTS OF CODE
// LOOKS HORRIBLE
// LOTS OF CODE
// VERY MESSY
// LOTS OF CODE
}
// MANY OTHER METHODS
// MEANS VERY LARGE FILE WITH LOTS OF LINES OF CODE
}
Reason 2 To prevent multiple definition linker errors:
Perhaps this is the main reason why you would split implementation from declaration. In the above example, you could move the method body to outside the class. This would make it look much cleaner and structured. However, according to this question, the above example has implicit inline specifiers. Moving the implementation from within the class to outside the class, as in the example below, will cause you linker errors, and so you would either inline everything, or move the function definitions to a .cpp file.
Example: _The example below will cause "multiple definition linker errors" if you do not move the function definition to a .cpp file or specify the function as inline.
// my_class.hpp
void my_class::my_function()
{
// ERROR! MULTIPLE DEFINITION OF my_class::my_function
// This error only occurs if you #include the file containing this code
// in two or more separate source (compiled, .cpp) files.
}
To fix the problem:
//my_class.cpp
void my_class::my_function()
{
// Now in a .cpp file, so no multiple definition error
}
Or:
// my_class.hpp
inline void my_class::my_function()
{
// Specified function as inline, so okay - note: back in header file!
// The very first example has an implicit `inline` specifier
}
Reason 3 You want to save space, again, but this time you are working with a template class:
If we are working with template classes, then we cannot move the implementation to a source file (.cpp file). That's not currently allowed by (I assume) either the standard or by current compilers. Unlike the first example of Reason 2, above, we are allowed to place the implementation in the header file. According to this question the reason is that template class methods also have implied inline specifiers. Is that correct? (It seems to make sense.) But nobody seemed to know on the question I have just referenced!
So, are the two examples below identical?
// some_header_file.hpp
#pragma once
// template class declaration goes here
class some_class
{
// Some code
};
// Example 1: NO INLINE SPECIFIER
template<typename T>
void some_class::class_method()
{
// Some code
}
// Example 2: INLINE specifier used
template<typename T>
inline void some_class::class_method()
{
// Some code
}
If you have a template class header file, which is becoming huge due to all the functions you have, then I believe you are allowed to move the function definitions to another header file (usually a .tpp file?) and then #include file.tpp at the end of your header file containing the class declaration. You must NOT include this file anywhere else, however, hence the .tpp rather than .hpp.
I assume you could also do this with the inline methods of a regular class? Is that allowed also?
Question Time
So I have made some statements above, most of which relate to the structuring of source files. I think everything I said was correct, because I did some basic research and "found out some stuff", but this is a question and so I don't know for sure.
What this boils down to, is how you would organize code within files. I think I have figured out a structure which will always work.
Here is what I have come up with. (This is my class code file organization/structure standard, if you like. Don't know if it will be very useful yet, that's the point of asking.)
1: Declare the class (template or otherwise) in a .hpp file, including all methods, friend functions and data.
2: At the bottom of the .hpp file, #include a .tpp file containing the implementation of any inline methods. Create the .tpp file and ensure all methods are specified to be inline.
3: All other members (non-inline functions, friend functions and static data) should be defined in a .cpp file, which #includes the .hpp file at the top to prevent errors like "class ABC has not been declared". Since everything in this file will have external linkage, the program will link correctly.
Do standards like this exist in industry? Will the standard I came up with work in all cases?
Your three points sound about right. That's the standard way to do things (although I've not seen .tpp extension before, usually it's .inl), although personally I just put inline functions at the bottom of header files rather than in a separate file.
Here is how I arrange my files. I omit the forward declare file for simple classes.
myclass-fwd.h
#pragma once
namespace NS
{
class MyClass;
}
myclass.h
#pragma once
#include "headers-needed-by-header"
#include "myclass-fwd.h"
namespace NS
{
class MyClass
{
..
};
}
myclass.cpp
#include "headers-needed-by-source"
#include "myclass.h"
namespace
{
void LocalFunc();
}
NS::MyClass::...
Replace pragma with header guards according to preference..
The reason for this approach is to reduce header dependencies, which slow down compile times in large projects. If you didn't know, you can forward declare a class to use as a pointer or reference. The full declaration is only needed when you construct, create or use members of the class.
This means another class which uses the class (takes parameters by pointer/reference) only has to include the fwd header in its own header. The full header is then included in the second class's source file. This greatly reduces the amount of unneeded rubbish you get when pulling in a big header, which pulls in another big header, which pulls in another...
The next tip is the unnamed namespace (sometimes called anonymous namespace). This can only appear in a source file and it is like a hidden namespace only visible to that file. You can place local functions, classes etc here which are only used by the the source file. This prevents name clashes if you create something with the same name in two different files. (Two local function F for example, may give linker errors).
The main reason to separate interface from implementation is so that you don't have to recompile all of your code when something in the implementation changes; you only have to recompile the source files that changed.
As for "Declare the class (template or otherwise)", a template is not a class. A template is a pattern for creating classes. More important, though, you define a class or a template in a header. The class definition includes declarations of its member functions, and non-inine member functions are defined in one or more source files. Inline member functions and all template functions should be defined in the header, by whatever combination of direct definitions and #include directives you prefer.
Do standards like this exist in industry?
Yes. Then again, coding standards that are rather different from the ones you expressed can also be found in industry. You are talking about coding standards, after all, and coding standards range from good to bad to ugly.
Will the standard I came up with work in all cases?
Absolutely not. For example,
template <typename T> class Foo {
public:
void some_method (T& arg);
...
};
Here, the definition of class template Foo doesn't know a thing about that template parameter T. What if, for some class template, the definitions of the methods vary depending on the template parameters? Your rule #2 just doesn't work here.
Another example: What if the corresponding source file is huge, a thousand lines long or longer? At times it makes sense to provide the implementation in multiple source files. Some standards go to the extreme of dictating one function per file (personal opinion: Yech!).
At the other extreme of a thousand-plus line long source file is a class that has no source files. The entire implementation is in the header. There's a lot to be said for header-only implementations. If nothing else, it simplifies, sometimes significantly, the linking problem.

Templates and .cpp files

I am learning C++ and it hasn't been an enjoyable experience (compared to Java or VBA at least). I have the following code:
//This is in a number.h file
#pragma once
template <class T>
class number{
public:
T value1, value2, result;
public:
T add();
number(T value1_in, T value2_in);
};
//This is in a number.cpp file
template <class T>
number<T>::number(T value1_in, T value2_in){
value1 = value1_in;
value2 = value2_in;
}
template <class T>
T number<T>::add(){
result = value1 + value2;
return result;
}
//This is in main.cpp
#include "number.h"
#include <iostream>
using namespace std;
int main(){
int a = 2, b =3;
number<int> n1(a,b);
cout << n1.add();
system("pause");
return EXIT_SUCCESS;
}
Which of course gives me an error. Even though I am pretty sure it should work. More specifically I get a linker error. After 3 hours of looking at this I decided to include number.cpp in main.cpp and that magically made it work. What the hell is going on? I thought I only need to include the header file (I wrote a matrix class with a bunch of linear solvers for different algorithms before this and only included header files in the whole project). Is this C++ specific or compiler specific? (I am using Dev-C++ 4.9.9.2 which has Mingw I guess)
You do not have to put the entire definition into the header file; don't listen to what others tell you :-)
That is the conventional solution, and you and I will do it quite often, but it's not the only solution.
The other option is to simply place this line at the end of your number.cpp file, in order to force that particular template class to be instantiated and fully compiled there.
template class number<int>;
In short, there are two valid solutions. You can use this line, or you can copy the definition into the header file. Depending on context, one approach might be better than the other, but both are valid. See this answer of mine for a more comprehensive discussion of both approaches:
https://stackoverflow.com/a/8752879/146041
Templated classes or functions always need to stay in the header file.
The reason is that whenever you instantiate a template, the preprocessor (inside compiler) generates new code for exactly that kind of instantiation (e.g. number<double>). That's why the classes number<double> and number<int> will not share any relationship: They will be two completely different classes although both were generated from the same template.
For the compiler to be able to generate this code, it must know the whole template definition, not only its declaration. That's why a template needs to stay in the header in full.
Including the cpp file in your main.cpp did the trick, as it effectively became a header.
In C++, templates are just as their name suggests: templates for a class, function etc. As the concrete type of the template parameter is not known in advance, and the compiled object code depends on the actual parameter, they are not getting compiled (as normal classes and functions) until you use them in any other source file and the compiler gets to know what type should it substitute into the template parameter.
That's why all functions must be defined and implemented in the header file.
See the last section of this documentation or the answers for this similar question for further explanation.

c++ class with template cannot find its constructor

I have a problem I don't really understand. I have a class Node.
template<class T>
class node {
protected:
T _data;
public:
node(T data);
};
This is in "node.h" file. In "node.cpp" file, there is this constructor:
#include "node.h"
template<class T>
node<T>::node (T data) {
_data = data;
}
While the compiler finds no error, the linker (ld) tells me:
/usr/bin/ld: Undefined symbols:
node<int>::node(int)
the weird part... if I move the constructor from .cpp to .h file, everything works fine. Where is the problem?
The problem is that templates aren't classes - you don't normally write them in two separate files. Template classes are code that the compiler uses to generate classes. As such, your implementation code needs to effectively be inline, i.e., in the header as you discovered.
For a fuller explanation of why it has to be this way, see the C++ FAQ Lite.
As a general rule, you must put all template members inside of the header file. Templates are compiled in an as-used basis, and hence the entire definition needs to be available wherever they are used. Putting the code in the header file will solve that problem.
The only time you can put a template definition in a CPP file is when the template will only be used within that CPP file. The reason being is that it meets the standard that the entire definition is available for compilation.
Moving the contents of node.cpp to node.h will fix the problem.
Strange Scenarios
Then again, you can also put everything in a CPP file and include the CPP file. C++ is flexible in this way. I only mention this because I've seen in done before. I actually bruised my jaw when it hit the top of my desk.
When you use node<int>, you have not most likely included node.cpp. Therefore the compiler cannot instantiate the node<int>::node<int> constructor. Usually you put all the template code, including all the implementations of the methods, in the header file, or something included from it.
The commonly accepted practice is to put all of the implementation in the .h file, so that the classes can be generated from the template as needed.
If you know ahead of time which types your template will be instantiated with, you might be able to cheat a little. Just make sure your .cpp includes a use case for each type and method you will need. It is important that the use case come after the template code. E.g. for "node.cpp", use
#include "node.h"
template<class T>
node<T>::node (T data) {
_data = data;
}
void dummy(void)
{
node<int> intnode(0);
node<double> doublenode(0.0);
}
// You can put templates declaration in header and definition in source
// node.h or wherever you include file gets included
extern template class node<int>;
// node.cpp or where ever source file you want to use it
// But use it only once for each type of generated class
template class node<int>;
Unless there's a call to the function, the compiler won't output any code and the linker won't find it.
You should put the function in the header where it belongs.
implicit instantiation is turned off, you need
template class node<int>;
somewhere in your code (node.cpp maybe)
EDIT: bad answer, it's probably not the case.