Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this trying to find the destructor twice?

I was trying out the following piece of code:

GeneralTemplate.h

#ifndef _GENERATEMPLATE_H_
#define _GENERATEMPLATE_H_

#include <iostream>

template <class T>
class GeneralTemplate
{
  public:
  GeneralTemplate();
  GeneralTemplate(const GeneralTemplate &g);
  
  ~GeneralTemplate();
  
  GeneralTemplate& operator= (GeneralTemplate const& g);
  
  template <class M>
  void arbitraryFunction(const M &m);
};

#endif

main.cpp

#include "GeneralTemplate.h"

#include <iostream>

int main()
{
    GeneralTemplate<int> gInt;
    gInt.arbitraryFunction(2.3);
    return 0;
}

Note that I don't have any implementation for the member functions of the class template. But that is not the problem. I know how to do that! If I try to compile main.cpp, I should get a linking error and that's what I get. The question is why is it trying to find the destructor twice (last two lines of error below).

$g++ main.cpp 
/tmp/cckrdPCs.o: In function `main':
main.cpp:(.text+0x13): undefined reference to `GeneralTemplate<int>::GeneralTemplate()'
main.cpp:(.text+0x34): undefined reference to `void GeneralTemplate<int>::arbitraryFunction<double>(double const&)'
main.cpp:(.text+0x45): undefined reference to `GeneralTemplate<int>::~GeneralTemplate()'
main.cpp:(.text+0x61): undefined reference to `GeneralTemplate<int>::~GeneralTemplate()'
collect2: ld returned 1 exit status
like image 774
toutnom Avatar asked Oct 16 '14 23:10

toutnom


1 Answers

It's most likely related to exception safety. If arbitraryFunction throws an exception, the stack needs to be unwound, meaning gInt needs to be destroyed early. Since this is all happening in main, where no further unwinding is ever going to happen, it's doubtful whether it really needs two calls to the destructor.... but the behavior you're observing is not entirely off the wall.

like image 168
Sneftel Avatar answered Sep 28 '22 09:09

Sneftel