result_of problem with VC8 (header depdendencies)

The following code generates a compile error with VC8+SP1: ************************************************************************** #include <boost/lambda/lambda.hpp> #if 1 // compiles when set to 0 # include <boost/utility/result_of.hpp> # include <boost/range/functions.hpp> #else # include <boost/range/functions.hpp> # include <boost/utility/result_of.hpp> #endif #include <boost/function.hpp> #include <boost/type_traits/is_same.hpp> typedef boost::function< int ( void ) > FuncType; BOOST_STATIC_ASSERT( ( boost::is_same< boost::result_of< FuncType ()
::type, int >::value ) );
This compiles with intel C++ 9.1. Change the inclusion order of result_of and functions.hpp and it compiles with VC8 too. Looks like a bug in VC8. Does anybody know any workaround for this besides enforcing the header order? Regards, Sean

AMDG Sean Huang wrote:
The following code generates a compile error with VC8+SP1:
************************************************************************** #include <boost/lambda/lambda.hpp> #if 1 // compiles when set to 0 # include <boost/utility/result_of.hpp> # include <boost/range/functions.hpp> #else # include <boost/range/functions.hpp> # include <boost/utility/result_of.hpp> #endif
#include <boost/function.hpp> #include <boost/type_traits/is_same.hpp>
typedef boost::function< int ( void ) > FuncType;
BOOST_STATIC_ASSERT( ( boost::is_same< boost::result_of< FuncType ()
::type, int >::value ) );
I've traced the problem as far back as I can: #include <boost/mpl/has_xxx.hpp> namespace boost { namespace lambda { namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type); } } } namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_apply, apply, false) }}} #include <boost/mpl/assert.hpp> struct with_result_type { typedef int result_type; }; BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type); BOOST_MPL_ASSERT((has_result_type<with_result_type>)); In Christ, Steven Watanabe

On Mon, Jun 2, 2008 at 7:08 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Sean Huang wrote:
The following code generates a compile error with VC8+SP1:
************************************************************************** #include <boost/lambda/lambda.hpp> #if 1 // compiles when set to 0 # include <boost/utility/result_of.hpp> # include <boost/range/functions.hpp> #else # include <boost/range/functions.hpp> # include <boost/utility/result_of.hpp> #endif
#include <boost/function.hpp> #include <boost/type_traits/is_same.hpp>
typedef boost::function< int ( void ) > FuncType;
BOOST_STATIC_ASSERT( ( boost::is_same< boost::result_of< FuncType ()
::type, int >::value ) );
I've traced the problem as far back as I can:
#include <boost/mpl/has_xxx.hpp>
namespace boost { namespace lambda { namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type);
} } }
namespace boost { namespace mpl { namespace aux { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_apply, apply, false) }}}
#include <boost/mpl/assert.hpp>
struct with_result_type { typedef int result_type; };
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type);
BOOST_MPL_ASSERT((has_result_type<with_result_type>));
Wow. Way to track down a really obscure bug! So, MPL's has_xxx is the culprit. I played around with has_xxx quite a bit once, and I remember template-based sfinae can be finicky between compilers. From what I can tell in Steve's example, ::has_result_type, ::boost::mpl::aux::has_apply, ::boost::lambda::detail::has_result_type all share the same substitute - ::boost::mpl::aux::msvc71_sfinae_helper. The problem appears to be triggered by the order in which templates using this substitute are specialized - definitely a bug in msvc. Boost can work around the problem by using a different substitute helper for each has_xxx. The attached patch shows one way to do this and appears to fix the problem. Daniel Walker

From: "Daniel Walker" <daniel.j.walker@gmail.com>
::boost::mpl::aux::msvc71_sfinae_helper. The problem appears to be triggered by the order in which templates using this substitute are specialized - definitely a bug in msvc.
or maybe demonstration of potential issues related to order of explicit specializations, documented in C++ standard, clause 14.7.3/7 ? B. PS. sorry, could not resist ;)

On Tue, Jun 3, 2008 at 12:20 PM, Bronek Kozicki <brok@spamcop.net> wrote:
From: "Daniel Walker" <daniel.j.walker@gmail.com>
::boost::mpl::aux::msvc71_sfinae_helper. The problem appears to be triggered by the order in which templates using this substitute are specialized - definitely a bug in msvc.
or maybe demonstration of potential issues related to order of explicit specializations, documented in C++ standard, clause 14.7.3/7 ?
B.
PS. sorry, could not resist ;)
Yes, good point. Thanks for that reference! I think the following may be the greatest sentence in the standard: "When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation." Kindle its self-immolation! Ha! That's classic. So, I shouldn't have called it a bug. Maybe you could call this a spark! Or dry kindling? But still, the authors of more recent msvc compilers as well as compilers from other vendors seem to have arrived an interpretation of the standard that doesn't give rise to this peculiar behavior. So, at least for more recent compilers, user intuitions/expectations won't be so disappointed... or rather, won't be burnt to a crisp! Daniel Walker
participants (4)
-
Bronek Kozicki
-
Daniel Walker
-
Sean Huang
-
Steven Watanabe