christophgysin / googlemock

Automatically exported from code.google.com/p/googlemock
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Microsoft produces linker errors when user code uses identical DoAll invocations in in two files. #21

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
From the user email:

//test1.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace testing;

#include <iostream>
using namespace std;

class test1
{
public:
       virtual int get(string *name)=0;
};

class mock_test1: public test1
{
public:
       MOCK_METHOD1(get, int(string *name));
};

class use_test1
{
public:
       explicit use_test1(test1 *ptr_test1):
               ptr_test1_(ptr_test1)
       {

       }
       void use_get()
       {
               string name;
               int ret=ptr_test1_->get(&name);
               cout<<"ret="<<ret<<" name="<<name<<endl;
       }
private:
       test1 *ptr_test1_;
};

TEST(use_test1, test1)
{
       mock_test1 mock_test1_obj;
       EXPECT_CALL(mock_test1_obj, get(_))
               .WillOnce(DoAll(SetArgumentPointee<0>(string("ddd")),
                                               Return(0)));

       use_test1 use_test1_obj(&mock_test1_obj);
       use_test1_obj.use_get();
}

// test2.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace testing;

#include <iostream>
using namespace std;

class test2
{
public:
       virtual int get(string *name)=0;
};

class mock_test2: public test2
{
public:
       MOCK_METHOD1(get, int(string *name));
};

class use_test2
{
public:
       explicit use_test2(test2 *ptr_test2):
       ptr_test2_(ptr_test2)
       {

       }
       void use_get()
       {
               string name;
               int ret=ptr_test2_->get(&name);
               cout<<"ret="<<ret<<" name="<<name<<endl;
       }
private:
       test2 *ptr_test2_;
};

TEST(use_test2, test2)
{
       mock_test2 mock_test2_obj;
       EXPECT_CALL(mock_test2_obj, get(_))
               .WillOnce(DoAll(SetArgumentPointee<0>(string("ddd")),
               Return(0)));

       use_test2 use_test2_obj(&mock_test2_obj);
       use_test2_obj.use_get();
}

error when linking:
test2.obj : error LNK2005: "public: __thiscall `public: __thiscall
testing::internal::DoBothAction<class testing::PolymorphicAction<class
testing::internal::SetArgumentPointeeAction<0,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,0> >,class testing::internal::ReturnAction<int>
>::operator<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)> class
testing::Action<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)>(void)const
'::`2'::Impl::Impl(class testing::Action<void __cdecl(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *)> const &,class testing::Action<int __cdecl
(class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *)> const &)" (??0Impl@?1???$?B$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z@?
$DoBothAction@V?$PolymorphicAction@V?$SetArgumentPointeeAction@$0A@V?
$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@
$0A@@internal@testing@@@testing@@V?
$ReturnAction@H@internal@2@@internal@testing@@QBE?AV?$Action@$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@3@XZ@QAE@ABV?$Action@$$A6AXPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@3@ABV43@@Z) 已经在 test1.obj 中定义
test2.obj : error LNK2005: "public: virtual int __thiscall `public:
__thiscall testing::internal::DoBothAction<class
testing::PolymorphicAction<class
testing::internal::SetArgumentPointeeAction<0,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,0> >,class testing::internal::ReturnAction<int>
>::operator<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)> class
testing::Action<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)>(void)const
'::`2'::Impl::Perform(struct boost::fusion::tuple<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_> const &)" (?
Perform@Impl@?1???$?B$$A6AHPAV?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@?$DoBothAction@V?$PolymorphicAction@V?
$SetArgumentPointeeAction@$0A@V?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@$0A@@internal@testing@@@testing@@V?
$ReturnAction@H@internal@2@@internal@testing@@QBE?AV?$Action@$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@4@XZ@UAEHABU?$tuple@PAV?$basic_string@DU?
$char_traits@D@std@@V?
$allocator@D@2@@std@@Uvoid_@fusion@boost@@U345@U345@U345@U345@U345@U345@U345@U34
5@@fusion@boost@@@Z)
已经在 test1.obj 中定义
test2.obj : error LNK2005: "public: __thiscall `public: __thiscall
testing::internal::DoBothAction<class testing::PolymorphicAction<class
testing::internal::SetArgumentPointeeAction<0,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,0> >,class testing::internal::ReturnAction<int>
>::operator<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)> class
testing::Action<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)>(void)const
'::`2'::Impl::Impl(class testing::Action<void __cdecl(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *)> const &,class testing::Action<int __cdecl
(class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *)> const &)" (??0Impl@?1???$?B$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z@?
$DoBothAction@V?$PolymorphicAction@V?$SetArgumentPointeeAction@$0A@V?
$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@
$0A@@internal@testing@@@testing@@V?
$ReturnAction@H@internal@2@@internal@testing@@QBE?AV?$Action@$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@3@XZ@QAE@ABV?$Action@$$A6AXPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@3@ABV43@@Z) 已经在 test1.obj 中定义
test2.obj : error LNK2005: "public: virtual int __thiscall `public:
__thiscall testing::internal::DoBothAction<class
testing::PolymorphicAction<class
testing::internal::SetArgumentPointeeAction<0,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,0> >,class testing::internal::ReturnAction<int>
>::operator<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)> class
testing::Action<int __cdecl(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > *)>(void)const
'::`2'::Impl::Perform(struct boost::fusion::tuple<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > *,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_,struct
boost::fusion::void_,struct boost::fusion::void_> const &)" (?
Perform@Impl@?1???$?B$$A6AHPAV?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@?$DoBothAction@V?$PolymorphicAction@V?
$SetArgumentPointeeAction@$0A@V?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@$0A@@internal@testing@@@testing@@V?
$ReturnAction@H@internal@2@@internal@testing@@QBE?AV?$Action@$$A6AHPAV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@@Z@4@XZ@UAEHABU?$tuple@PAV?$basic_string@DU?
$char_traits@D@std@@V?
$allocator@D@2@@std@@Uvoid_@fusion@boost@@U345@U345@U345@U345@U345@U345@U345@U34
5@@fusion@boost@@@Z)
已经在 test1.obj 中定义

Original issue reported on code.google.com by vladlosev on 23 Jan 2009 at 1:07

GoogleCodeExporter commented 9 years ago
This appears to be a bug in the Microsoft compiler which generates global 
symbols for
methods of templated classes defined inside templated functions. The linker them
cannot collapse such multiple definitions and reports symbol collisions.

Original comment by vladlosev on 23 Jan 2009 at 1:10

GoogleCodeExporter commented 9 years ago
Fixed by Vlad in the trunk.

Original comment by zhanyong...@gmail.com on 19 Feb 2009 at 10:32