2

Using this tutorial Makefile I want to build a simple program with a separate compiling, The main problem is that the IDE Eclpse Indigo C\C++ (prespective) or MinGW I cannot compile the files. The error which I get is :

undefined reference to double getAverage<int, 85u>(int (&) [85u])'
undefined reference to int getMax<int, 85u>(int (&) [85u])'
undefined reference to int getMin<int, 85u>(int (&) [85u])'
undefined reference to void print<int, 85u>(int (&) [85u])'
undefined reference to void sort<int, 85u>(int (&) [85u])'
undefined reference to void print<int, 85u>(int (&) [85u])'

The main.cpp file is this :

#include "Tools.h"
#include <iostream>
using namespace std;

int main(int argc,char* argv[])
{
int numbers[] = {1,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8,-2,7,14,5,6,16,8};
cout <<"Average = "<< getAverage(numbers) << endl;
cout <<"Max element = "<< getMax(numbers) << endl;
cout <<"Minimal element = "<< getMin(numbers) << endl;
print(numbers);
sort(numbers);
print(numbers);
return 0;
}

and I have a Tools.h file :

#ifndef TOOLS_H_
#define TOOLS_H_
#include <iostream>
int getBigger(int numberOne,int numberTwo);
template <typename T,size_t N> double getAverage(T (&numbers)[N]);
template <typename T,size_t N> T getMax(T (&numbers)[N]);
template <typename T,size_t N> T getMin(T (&numbers)[N]);
/**
 * Implementing a simple sort method of big arrays
 */
template <typename T,size_t N> void sort(T (&numbers)[N]);
/**
 * Implementing a method for printing arrays
 */
template <typename T,size_t N> void print(T (&numbers)[N]);
#endif
Mat
  • 202,337
  • 40
  • 393
  • 406
Jordan Borisov
  • 1,603
  • 6
  • 34
  • 69
  • 2
    Where are the definitions of your functions? Since you are using templates, you should probably include them in the header (.h). See [Why can templates only be implemented in the header file?](http://stackoverflow.com/q/495021/20984). – Luc Touraille Jan 30 '12 at 14:15
  • The definitions of the functions are in the Tools.cpp file. – Jordan Borisov Jan 30 '12 at 14:22

4 Answers4

2

When you compile Tools.cpp your compiler has no idea about the template parameters that you have used in main.cpp. Therefore it compiles nothing related to this templates.

You need to include theses template definitions from the compilation unit that uses them. The file Tools.cpp is often renamed to something like Tools.inl to indicate that it's neither a header file nor a separate compilation unit.

The compilation unit "main.cpp" could look like this:

#include "tools.h"
#include "tools.inl"

main()
{
    int number[] = {1,2,3};
    getaverage(numbers);
}

Since the compiler identifies the required specialization it can generate the code from the implementation file.

harper
  • 13,345
  • 8
  • 56
  • 105
  • I change the Tools.cpp extension to Tools.ini but there is still a problem with undefined reference to the functions. – Jordan Borisov Jan 31 '12 at 10:21
  • But when I define the functions in the header file everything is fine. – Jordan Borisov Jan 31 '12 at 10:26
  • It's okay to define the functions in the header file since they are inline functions. The code is generated when your code needs an implementation. You need only a separate file, if you think the header file describes the interface and should not be cluttered up with implementation details. – harper Jan 31 '12 at 15:26
  • @JordanBorisov: if you do the rename to .inl (not ini), then the header should _include_ the inl file. – Mooing Duck Feb 01 '12 at 16:14
1

For most cases, harper's answer is appropriate. But for completeness' sake, explicit template instantiation should also be mentioned.

When you include the implementation in every compilation unit, your template classes and functions will be instantiated and compiled in all of them. Sometimes, this is not desirable. It is mostly due to compile-time memory restrictions and compilation time, if your template classes and functions are very complicated. This becomes a very real issue when you, or the libraries you use rely heavily on template metaprogramming. Another situation could be that your template function implementations might be used in many compilation units, and when you change the implementation, you will be forced to re-compile all those compilation units.

So, the solution in these situations is to include a header file like your tools.h, and have a tools.cpp, implementing the templates. The catch is that, you should explicitly instantiate your templates for all the template arguments that will be used throughout your program. This is accomplished via adding the following to tools.cpp:

template double getAverage<int,85>(int (&numbers)[85]);

Note: You obviously have to do something about that "85", such as defining it in a header file and using it across tools.cpp and main.cpp

enobayram
  • 4,650
  • 23
  • 36
  • Yes, I forget to mention this. And I think it's the intentional object to have a "separate compiling" as it wask asked. – harper Feb 01 '12 at 17:23
0

I've found this article which is useful : templates and header files

I declared the function in the Tools.h file and include there the file Tool.hpp and after this I defined them in the Tools.hpp file.

Jordan Borisov
  • 1,603
  • 6
  • 34
  • 69
0

I haven't tried to compile .cpp and .c files together but maybe my example will help.

I had similar problem compiling two separate assembly files .s on mingw with standard gcc compiler and i achieved it as follows:

gcc -m32 -o test test.s hello.s

-m32 means i'm compiling 32bit code

-o is the output file ( which in my example is the "test" file )

test.s and hello.s are my source files. test.s is the main file and hello.s has the helper function. (Oh, to mention is the fact that both files are in the same directory)

orustammanapov
  • 1,792
  • 5
  • 25
  • 44