[utility/result_of] decltype-based implementation breaking valid code on msvc-10

I recently looked into some proto failures on msvc-10 and traced them back to the use of decltype in the implementation of boost::result_of. The program below demonstrates the problem: // Uncomment the next line to make the problem go away //#define BOOST_NO_DECLTYPE #include <boost/utility/result_of.hpp> template<class X, class Y> struct pair {}; template<class Base> struct S; struct wrapper { template<class T> struct result; template<class This, typename That> struct result<This(That)> { typedef S<That> type; }; template<typename That> typename result<wrapper(That)>::type operator()(That) const { return 0; } }; template<class T> struct S { S(int = 0) {} typename boost::result_of<wrapper(pair<T, T>)>::type foo() { return 0; } }; int main() { S<int> s; } The use of decltype in result_of causes the compiler to recursively instantiate templates until it blows its stack. To make the problem go away, you must #define BOOST_NO_DECLTYPE. I suspect the real problem is in a buggy implementation of decltype on msvc-10. For the upcoming boost release, I suggest that we stick with the non-decltype implementation of result_of on msvc-10, or risk massively breaking users' code, not to mention proto, spirit and xpressive on that compiler. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 4/5/2010 2:59 PM, Eric Niebler wrote:
I recently looked into some proto failures on msvc-10 and traced them back to the use of decltype in the implementation of boost::result_of. The program below demonstrates the problem: <snip>
https://svn.boost.org/trac/boost/ticket/4072 A patch is attached to the ticket. I've confirmed that it un-breaks proto on msvc-10, but have not tested it further. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Mon, Apr 5, 2010 at 6:39 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/5/2010 2:59 PM, Eric Niebler wrote:
I recently looked into some proto failures on msvc-10 and traced them back to the use of decltype in the implementation of boost::result_of. The program below demonstrates the problem:
<snip>
https://svn.boost.org/trac/boost/ticket/4072
A patch is attached to the ticket. I've confirmed that it un-breaks proto on msvc-10, but have not tested it further.
Good catch. Seems reasonable to me. In general, if some vendor releases an inadequate std:result_of or decltype, it would be good to have boost::result_of as a functional fallback, which is yet another reason to resolve the lambda/result_of issue. Enabling lambda to support boost::result_of's signature protocol, as in ticket 864, would do the trick. That way msvc-10 users would be able to enjoy lambda/result_of compatibility, even if msvc-10 still has some wrinkles. ~Daniel

On 5 April 2010 22:59, Eric Niebler <eric@boostpro.com> wrote:
I suspect the real problem is in a buggy implementation of decltype on msvc-10. For the upcoming boost release, I suggest that we stick with the non-decltype implementation of result_of on msvc-10, or risk massively breaking users' code, not to mention proto, spirit and xpressive on that compiler.
I think this is my fault. I was updating the use of config macros, which caused it to use decltype for Visual C++ 10. For other libraries I submitted tickets but since no one seemed to be maintaining result_of I made that change myself. I'll revert it for now but we should probably change config to define BOOST_NO_DECLTYPE for Visual C++ 10 if it's buggy on that compiler. Daniel

On Tue, Apr 6, 2010 at 3:52 AM, Daniel James <dnljms@gmail.com> wrote:
On 5 April 2010 22:59, Eric Niebler <eric@boostpro.com> wrote:
I suspect the real problem is in a buggy implementation of decltype on msvc-10. For the upcoming boost release, I suggest that we stick with the non-decltype implementation of result_of on msvc-10, or risk massively breaking users' code, not to mention proto, spirit and xpressive on that compiler.
I think this is my fault. I was updating the use of config macros, which caused it to use decltype for Visual C++ 10. For other libraries I submitted tickets but since no one seemed to be maintaining result_of I made that change myself. I'll revert it for now but we should probably change config to define BOOST_NO_DECLTYPE for Visual C++ 10 if it's buggy on that compiler.
Well, msvc-10 decltype may have enough functionality for some libraries, but not enough for others. BOOST_NO_DECLTYPE should probably indicate the availability of the keyword. As we discover more, other macros may be needed to account for quirks in different compilers. I would suggest defining BOOST_NO_DECLTYPE only on platforms that do not attempt to implement it. If a particular decltype implementation doesn't work for result_of, then for that compiler result_of can fallback to querying result<>. Of course, I almost forgot, this should be mentioned in the user documentation for result_of Daniel Walker Daniel Walker

On 4/6/2010 12:52 AM, Daniel James wrote:
I'll revert it for now but we should probably change config to define BOOST_NO_DECLTYPE for Visual C++ 10 if it's buggy on that compiler.
I had a similar thought. Here is the bug I filed against msvc: https://connect.microsoft.com/VisualStudio/feedback/details/548883 And for easy reference, here is the code: template<class T> struct S; template<class X, class Y> struct pair {}; template<class T> S<T> wrap(T) { return 0; } template<class T> struct S { S(int = 0) {} // The following use of decltype causes the compiler to blow up: decltype(wrap(pair<T,T>())) foo() { return wrap(pair<T,T>()); } // The following, which should be equivalent, compiles without // problem: //S<pair<T,T> > foo() { return wrap(pair<T,T>()); } }; int main() { S<int> s; } As you can see, decltype forces the types used in the expression to be complete. I'm not sure if that's conforming, but I hope not. I'd say it's premature to turn decltype on across the board for this compiler until we have a better idea of its limitations. The safe thing to do for 1.43 is to turn it off. We can always turn it on for 1.44. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
I suspect the real problem is in a buggy implementation of decltype on msvc-10. For the upcoming boost release, I suggest that we stick with the non-decltype implementation of result_of on msvc-10, or risk massively breaking users' code, not to mention proto, spirit and xpressive on that compiler.
MSVC10 isn't even released yet. Why bother with a non-stable compiler?

Mathias Gaunard wrote:
MSVC10 isn't even released yet. Why bother with a non-stable compiler?
Good question. It will be released in a few days, and we basically expect that the behavior of the final compiler will closely match the behavior of the RC. I also know of an issue of Boost.Iterator with MSVC-10 (<http://lists.boost.org/Archives/boost/2010/03/163133.php>), but I will wait until the final release of MSVC-10 is available before I start to push on it. One reason to start early with a non-stable compiler is that misbehavior in core libraries like utility/result_of or Boost.Iterator causes failures in dependent libraries, and these indirect failures can be difficult and time consuming to track down. Regards, Thomas
participants (5)
-
Daniel James
-
Daniel Walker
-
Eric Niebler
-
Mathias Gaunard
-
Thomas Klimpel