[1.36][ublas] VC8/SP1 with ADL problem?

Hi! Posting to devel, since I believe sucking ADL may be the cause ... I have a headache problem with VC8/SP1 which leads to some questions. 1. Can you confirm this behaviour? 2. Do you have a quick fix workaround for this? 3. Can this be fixed in future versions of boost The following innocent looking piece of code (boiled down within 2 days -sigh) ---snip--- #include <boost/numeric/interval.hpp> #include <boost/numeric/ublas/traits.hpp> #include <boost/numeric/ublas/vector.hpp> namespace ublas = boost::numeric::ublas; void trigger_ublas_compile_error() { ublas::vector<double> boom = ublas::zero_vector<double>(5); } ---EOF--- compiled with VC8 SP1 in DEBUG mode with a command line similar to (some private include paths ripped off) /Od /I "PATH_TO\boost_1_36_beta" /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_SCL_SECURE_NO_WARNINGS" /D "BOOST_PYTHON_STATIC_LIB" /D "_MBCS" /Gm /EHsc /RTC1 /MTd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt /bigobj bails out with ------ Build started: Project: XXXX, Configuration: Debug Win32 ------ Compiling... TestBoostUblasError.cpp [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : error C2784: 'boost::numeric::interval<T,Policies> boost::numeric::sqrt (const boost::numeric::interval<T,Policies> &)' : could not deduce template argument for 'const boost::numeric::interval<T,Policies> &' from 'const double' [...]\boost_1_36_beta\boost\numeric\interval\arith2.hpp(198) : see declaration of 'boost::numeric::sqrt' [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(93) : while compiling class template member function 'double boost::numeric::ublas::scalar_traits<T>::type_sqrt(const double &)' with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(151) : see reference to class template instantiation 'boost::numeric::ublas::scalar_traits<T>' being compiled with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : fatal error C1903: unable to recover from previous error(s); stopping compilation [...] ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Ugly as it is: it will compile in any release mode, be it static or dynamic linkage :-(

Here is my "workaround", which is ugly, but works until this is fixed #include <cmath> #include <cstdlib> #include <algorithm> #include <boost/numeric/ublas/detail/config.hpp> namespace boost { namespace numeric { namespace ublas { template<class T> struct type_traits; template<class T> struct scalar_traits; template<> struct scalar_traits<double> { typedef scalar_traits<double> self_type; typedef double value_type; typedef const double &const_reference; typedef double &reference; typedef double real_type; typedef real_type precision_type; // we do not know what type has more precision then the real_type static const unsigned plus_complexity = 1; static const unsigned multiplies_complexity = 1; static BOOST_UBLAS_INLINE real_type real (const_reference t) { return t; } static BOOST_UBLAS_INLINE real_type imag (const_reference /*t*/) { return 0; } static BOOST_UBLAS_INLINE value_type conj (const_reference t) { return t; } static BOOST_UBLAS_INLINE real_type type_abs (const_reference t) { // we'll find either std::abs or else another version via ADL: using namespace std; return abs (t); } static BOOST_UBLAS_INLINE value_type type_sqrt (const_reference t) { using namespace std; // force a type conversion back to value_type for intgral types // we'll find either std::sqrt or else another version via ADL: return value_type (sqrt (t)); } static BOOST_UBLAS_INLINE real_type norm_1 (const_reference t) { return self_type::type_abs (t); } static BOOST_UBLAS_INLINE real_type norm_2 (const_reference t) { return self_type::type_abs (t); } static BOOST_UBLAS_INLINE real_type norm_inf (const_reference t) { return self_type::type_abs (t); } static BOOST_UBLAS_INLINE bool equals (const_reference t1, const_reference t2) { static double const eps = std::sqrt(std::numeric_limits<double>::epsilon ()); return ((t1 - t2) < eps * (std::max)(((std::max)(std::abs(t1), std::abs(t2))), std::sqrt ((std::numeric_limits<double>::min)()))); } }; }}} #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/interval.hpp> namespace ublas = boost::numeric::ublas; void trigger_ublas_compile_error() { ublas::vector<double> boom = ublas::zero_vector<double>(5); }

Hello Markus,
1. Can you confirm this behaviour?
I can confirm this (VC8, debug).
2. Do you have a quick fix workaround for this?
How about "#define NDEBUG" :-) I'm no expert on ADL, so I have no idea whether VC8 is allowed to fail here. VC8 seems to fail as soon as I define any template function named sqrt inside the boost or boost::numeric namespace. I have no idea how to work around that. Perhaps I should investigate why "#define NDEBUG" works around the problem.
3. Can this be fixed in future versions of boost
I don't even know what causes the problem in the first place. Moving numeric/interval to a separate namespace would probably avoid the current problem, but this is not what I would call "fixed". I think you should report the problem to the ublas mailing list, where you initially also reported your "non-boiled down" problem. Regards, Thomas -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Markus Werle Sent: Mittwoch, 6. August 2008 11:28 To: boost@lists.boost.org Subject: [boost] [1.36][ublas] VC8/SP1 with ADL problem? Hi! Posting to devel, since I believe sucking ADL may be the cause ... I have a headache problem with VC8/SP1 which leads to some questions. 1. Can you confirm this behaviour? 2. Do you have a quick fix workaround for this? 3. Can this be fixed in future versions of boost The following innocent looking piece of code (boiled down within 2 days -sigh) ---snip--- #include <boost/numeric/interval.hpp> #include <boost/numeric/ublas/traits.hpp> #include <boost/numeric/ublas/vector.hpp> namespace ublas = boost::numeric::ublas; void trigger_ublas_compile_error() { ublas::vector<double> boom = ublas::zero_vector<double>(5); } ---EOF--- compiled with VC8 SP1 in DEBUG mode with a command line similar to (some private include paths ripped off) /Od /I "PATH_TO\boost_1_36_beta" /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_SCL_SECURE_NO_WARNINGS" /D "BOOST_PYTHON_STATIC_LIB" /D "_MBCS" /Gm /EHsc /RTC1 /MTd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt /bigobj bails out with ------ Build started: Project: XXXX, Configuration: Debug Win32 ------ Compiling... TestBoostUblasError.cpp [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : error C2784: 'boost::numeric::interval<T,Policies> boost::numeric::sqrt (const boost::numeric::interval<T,Policies> &)' : could not deduce template argument for 'const boost::numeric::interval<T,Policies> &' from 'const double' [...]\boost_1_36_beta\boost\numeric\interval\arith2.hpp(198) : see declaration of 'boost::numeric::sqrt' [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(93) : while compiling class template member function 'double boost::numeric::ublas::scalar_traits<T>::type_sqrt(const double &)' with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(151) : see reference to class template instantiation 'boost::numeric::ublas::scalar_traits<T>' being compiled with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : fatal error C1903: unable to recover from previous error(s); stopping compilation [...] ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Ugly as it is: it will compile in any release mode, be it static or dynamic linkage :-( _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

2. Do you have a quick fix workaround for this?
How about "#define NDEBUG" :-)
A better workaround is "#define BOOST_UBLAS_NDEBUG". However, this does not really fix the ADL problem, but just avoids the use of "type_traits<double>::type_sqrt" and "type_traits<double>::type_abs" for this example.
I'm no expert on ADL, so I have no idea whether VC8 is allowed to fail here.
I checked with VC9 and gcc-3.4.4 and they also fail. So this is probably not a bug in VC8, but a problem in ublas. I read a bit about ADL and came to the conclusion that an anonymous namespace might be one possible solution for this problem (see attached patch). At least it seems to work with both VC9 and gcc-3.4.4 for this example. (The intention behind ADL seems to be that the compiler looks in the namespace of the argument of the method call. So the lookup in the boost::numeric namespace doesn't seem to be intended. The anonymous namespace should avoid the lookup in the boost::numeric namespace, but still allow the lookup in the namespace of the argument of the method call.) Regards, Thomas -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Thomas Klimpel Sent: Donnerstag, 7. August 2008 20:33 To: boost@lists.boost.org Cc: ublas mailing list Subject: Re: [boost] [1.36][ublas] VC8/SP1 with ADL problem? Hello Markus,
1. Can you confirm this behaviour?
I can confirm this (VC8, debug).
2. Do you have a quick fix workaround for this?
How about "#define NDEBUG" :-) I'm no expert on ADL, so I have no idea whether VC8 is allowed to fail here. VC8 seems to fail as soon as I define any template function named sqrt inside the boost or boost::numeric namespace. I have no idea how to work around that. Perhaps I should investigate why "#define NDEBUG" works around the problem.
3. Can this be fixed in future versions of boost
I don't even know what causes the problem in the first place. Moving numeric/interval to a separate namespace would probably avoid the current problem, but this is not what I would call "fixed". I think you should report the problem to the ublas mailing list, where you initially also reported your "non-boiled down" problem. Regards, Thomas -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Markus Werle Sent: Mittwoch, 6. August 2008 11:28 To: boost@lists.boost.org Subject: [boost] [1.36][ublas] VC8/SP1 with ADL problem? Hi! Posting to devel, since I believe sucking ADL may be the cause ... I have a headache problem with VC8/SP1 which leads to some questions. 1. Can you confirm this behaviour? 2. Do you have a quick fix workaround for this? 3. Can this be fixed in future versions of boost The following innocent looking piece of code (boiled down within 2 days -sigh) ---snip--- #include <boost/numeric/interval.hpp> #include <boost/numeric/ublas/traits.hpp> #include <boost/numeric/ublas/vector.hpp> namespace ublas = boost::numeric::ublas; void trigger_ublas_compile_error() { ublas::vector<double> boom = ublas::zero_vector<double>(5); } ---EOF--- compiled with VC8 SP1 in DEBUG mode with a command line similar to (some private include paths ripped off) /Od /I "PATH_TO\boost_1_36_beta" /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_SCL_SECURE_NO_WARNINGS" /D "BOOST_PYTHON_STATIC_LIB" /D "_MBCS" /Gm /EHsc /RTC1 /MTd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt /bigobj bails out with ------ Build started: Project: XXXX, Configuration: Debug Win32 ------ Compiling... TestBoostUblasError.cpp [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : error C2784: 'boost::numeric::interval<T,Policies> boost::numeric::sqrt (const boost::numeric::interval<T,Policies> &)' : could not deduce template argument for 'const boost::numeric::interval<T,Policies> &' from 'const double' [...]\boost_1_36_beta\boost\numeric\interval\arith2.hpp(198) : see declaration of 'boost::numeric::sqrt' [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(93) : while compiling class template member function 'double boost::numeric::ublas::scalar_traits<T>::type_sqrt(const double &)' with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(151) : see reference to class template instantiation 'boost::numeric::ublas::scalar_traits<T>' being compiled with [ T=double ] [...]\boost_1_36_beta\boost\numeric\ublas\traits.hpp(97) : fatal error C1903: unable to recover from previous error(s); stopping compilation [...] ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Ugly as it is: it will compile in any release mode, be it static or dynamic linkage :-( _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Markus Werle
-
Thomas Klimpel