Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / September 2006

Tip: Looking for answers? Try searching our database.

std::transform with template function fails with /clr

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Richard B68 - 27 Jul 2006 12:00 GMT
Hello,
I'm porting some existing C++ code to VS2005 C++/CLI.

When I compile the following code with "No CLR support" it behaves as
expected (1 + 2 = 3) in all cases.  When I compile it with /clr then
transform call using addFunc<int> suggests that 1 + 2 = 8b001cc4.

Anyone know what's going on?

Thanks,
Richard.

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

// fixed type addition function.
int addInt32Func(const int& lhs,const int& rhs)
{
 return lhs + rhs;
}

// template version of addition function
template<typename T> T addFunc(const T& lhs,const T& rhs)
{
 return lhs + rhs;
}

// functor version of addition function
template<typename T> class addClass : public binary_function<T, T, T>
{
public:
 result_type operator()(
   const first_argument_type& lhs,
   const second_argument_type& rhs)
 {
   return (result_type)(lhs + rhs);
 }
};

int main(int argc, char* argv[])
{
 cout << "Single values " << endl;

 int a = 1, b = 2, c;

 c = addInt32Func(a, b);
 cout << "  addInt32Func           "
   << hex << a << " + " << b << " = " << c << endl;

 c = addFunc<int>(a, b);
 cout << "  addFunc<int>           "
   << hex << a << " + " << b << " = " << c << endl;

 c = addClass<int>()(a, b);
 cout << "  addClass<int>::addFunc "
   << hex << a << " + " << b << " = " << c << endl;

 cout << "Transform vector values" << endl;

 const int  = 2;
 vector<int> av(N_ELEM, 1), bv(N_ELEM, 2), cv(N_ELEM);
 
 std::transform(av.begin(),av.end(),bv.begin(),cv.begin(),addInt32Func);
 cout << "  addInt32Func           "
   << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;

 std::transform(av.begin(),av.end(),bv.begin(),cv.begin(),addFunc<int>);
 cout << "  addFunc<int>           "
   << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;

 std::transform(av.begin(),av.end(),bv.begin(),cv.begin(),addClass<int>());
 cout << "  addClass<int>()        "
    << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;
}
Barry Kelly - 27 Jul 2006 12:55 GMT
> When I compile the following code with "No CLR support" it behaves as
> expected (1 + 2 = 3) in all cases.  When I compile it with /clr then
> transform call using addFunc<int> suggests that 1 + 2 = 8b001cc4.
>
> Anyone know what's going on?

Interesting program sample. It looks awfully like a C++ compiler bug,
the problem being it's not always checking the calling convention of the
function template.

When compiled either without any CLR support, or with -clr:pure support,
it works. In mixed mode (i.e. just -clr), it doesn't work. Of course, it
doesn't even compile with -clr:safe.

I tried changing the templated function to a generic function - and in
that case, the problem goes away:

---8<---
generic<typename T> T addFunc(T lhs, T rhs)
{
 return lhs + rhs;
}
--->8---

Alternatively, sticking the function into a function pointer temporarily
also works:

---8<---
 int (*f)(const int&, const int&) = addFunc<int>;
 
 std::transform(av.begin(),av.end(),bv.begin(),cv.begin(),f);
 cout << "  f                      "
   << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;
--->8---

Finally, changing the calling convention to __clrcall also works:

---8<---
template<typename T>
T __clrcall addFunc(const T &lhs, const T &rhs)
{
 return lhs + rhs;
}

// ...

 int (__clrcall *f)(const int&, const int&) = addFunc<int>;
--->8---

I'd say you can file a bug based on your info.

-- Barry

Signature

http://barrkel.blogspot.com/

Barry Kelly - 27 Jul 2006 13:05 GMT
> I'd say you can file a bug based on your info.

Forgot to mention location: http://connect.microsoft.com/

-- Barry

Signature

http://barrkel.blogspot.com/

Richard B68 - 27 Jul 2006 13:37 GMT
> I'd say you can file a bug based on your info.
>
> -- Barry

Done.

Thanks for the validation.
Holger Grund - 27 Jul 2006 14:35 GMT
> When I compile the following code with "No CLR support" it behaves as
> expected (1 + 2 = 3) in all cases.  When I compile it with /clr then
> transform call using addFunc<int> suggests that 1 + 2 = 8b001cc4.

[..]

>  std::transform(av.begin(),av.end(),bv.begin(),cv.begin(),addInt32Func);
>  cout << "  addInt32Func           "
[quoted text clipped - 3 lines]
>  cout << "  addFunc<int>           "
>    << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;

I think I might have seen something like this. I had an issue once and
looked only very briefly into it. But I seem to recall managed code
indirectly calling into managed code via a double thunk
(caller=>Managed to Native=>Native to Managed=>callee)
where some of the thunking code clobbered an allocated register.

It might be the same issue for you. IIRC a free function would
be called via a statically declared virtual thunk while the template
specialization has its address taken via ldftn. I thought the CLR
should handle both cases in the same way, but apparently it
did not.

All that being said, I didn't have the time to look into it.

-hg
Richard B68 - 02 Aug 2006 08:30 GMT
Submitted as ID 171949 on connect.microsoft.com but it's all gone a bit dark.  

This shook my confidence in the compiler enough that I'll be sticking with
unmanaged C++ for a while.

> Hello,
> I'm porting some existing C++ code to VS2005 C++/CLI.
[quoted text clipped - 74 lines]
>      << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;
> }
Richard B68 - 06 Sep 2006 08:55 GMT
ID 171949 was close "Won't fix" without comment.  
Don't think I'll bother reporting any more bugs if that's the response.

> Submitted as ID 171949 on connect.microsoft.com but it's all gone a bit dark.  
>
[quoted text clipped - 79 lines]
> >      << hex << av[0] << " + " << bv[0] << " = " << cv[0] << endl;
> > }

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.