[cfe-users] Linking problem with implicit instantiation of constructor/destructor

2020-04-17 Thread Jaroslav Zeman via cfe-users
Hello,

I've run into wieird problem when trying to compile and link our programs with 
clang++ on linux instead of g++. It occurs, when:
 - template class member definitions are separated from the definition of the 
class
- no explicit instantiation is done
- member definitions are available only in some of the units, where the 
template is being used.
(Yeah, our code is a mess)

This is simple expamle:
// - template.h 
template< typename T >
struct Template {
  Template();
  ~Template();
};

void doSomething(Template& t);

// - template.cpp 
#include "template.h"

template< typename T >
Template< T >::Template() { }

template< typename T>
Template< T >::~Template() { }

void doSomething(Template& t) {
  Template new_t;
  t = new_t;
}

// - main.cpp 
#include "template.h"

int main(int argc_, char** argv_) {

  Template t;
  doSomething(t);

  return 0;
}
// - end of code

When compiled with clang++:
$ clang++ -o test main.cpp template.cpp 
/usr/bin/ld: /tmp/main-e2fa2c.o: in function `main':
main.cpp:(.text+0x2f): undefined reference to `Template::Template()'
/usr/bin/ld: main.cpp:(.text+0x4d): undefined reference to 
`Template::~Template()'
/usr/bin/ld: main.cpp:(.text+0x82): undefined reference to 
`Template::~Template()'

reading the object files using nm tool shows, the symbol for destructor 
instantiated in template.cpp is _ZN8TemplateIiED2Ev, but the main.o requires 
symbol _ZN8TemplateIiED1Ev. Notice the difference in one digit: D2 vs D1.

So symbol ...D1... is required, but only ...D2... is available. The D1 version 
is generated by clang only for explicit instantiation. g++ generates both D1 
and D2 for any type of instantiation.

Can this be considered a bug of clang++? Or does this behaior have some 
purpose?

Regards,
JZ


___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Linking problem with implicit instantiation of constructor/destructor

2020-04-17 Thread krokus via cfe-users
> $ clang++ -o test main.cpp template.cpp
>
>> /usr/bin/ld: /tmp/main-e2fa2c.o: in function `main':
> main.cpp:(.text+0x2f): undefined reference to `Template::Template()'
> /usr/bin/ld: main.cpp:(.text+0x4d): undefined reference to
> `Template::~Template()'
> /usr/bin/ld: main.cpp:(.text+0x82): undefined reference to
> `Template::~Template()'
>

What happens if you change the order of the .cpp files, putting
template.cpp first; is it stil unresolved?

clang++ -o test template.cpp main.cpp
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Linking problem with implicit instantiation of constructor/destructor

2020-04-17 Thread David Blaikie via cfe-users
I don't believe this code is valid according to C++. I believe it would
require an explicit instantiation of the ctor/dtor somewhere to make that
code valid - though I don't have chapter and verse on the spec at hand just
now to back that up.

On Fri, Apr 17, 2020 at 6:54 AM Jaroslav Zeman via cfe-users <
cfe-users@lists.llvm.org> wrote:

> Hello,
>
> I've run into wieird problem when trying to compile and link our programs
> with
> clang++ on linux instead of g++. It occurs, when:
>  - template class member definitions are separated from the definition of
> the
> class
> - no explicit instantiation is done
> - member definitions are available only in some of the units, where the
> template is being used.
> (Yeah, our code is a mess)
>
> This is simple expamle:
> // - template.h 
> template< typename T >
> struct Template {
>   Template();
>   ~Template();
> };
>
> void doSomething(Template& t);
>
> // - template.cpp 
> #include "template.h"
>
> template< typename T >
> Template< T >::Template() { }
>
> template< typename T>
> Template< T >::~Template() { }
>
> void doSomething(Template& t) {
>   Template new_t;
>   t = new_t;
> }
>
> // - main.cpp 
> #include "template.h"
>
> int main(int argc_, char** argv_) {
>
>   Template t;
>   doSomething(t);
>
>   return 0;
> }
> // - end of code
>
> When compiled with clang++:
> $ clang++ -o test main.cpp template.cpp
> /usr/bin/ld: /tmp/main-e2fa2c.o: in function `main':
> main.cpp:(.text+0x2f): undefined reference to `Template::Template()'
> /usr/bin/ld: main.cpp:(.text+0x4d): undefined reference to
> `Template::~Template()'
> /usr/bin/ld: main.cpp:(.text+0x82): undefined reference to
> `Template::~Template()'
>
> reading the object files using nm tool shows, the symbol for destructor
> instantiated in template.cpp is _ZN8TemplateIiED2Ev, but the main.o
> requires
> symbol _ZN8TemplateIiED1Ev. Notice the difference in one digit: D2 vs D1.
>
> So symbol ...D1... is required, but only ...D2... is available. The D1
> version
> is generated by clang only for explicit instantiation. g++ generates both
> D1
> and D2 for any type of instantiation.
>
> Can this be considered a bug of clang++? Or does this behaior have some
> purpose?
>
> Regards,
> JZ
>
>
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users