Weird regex compiler warnings with VC 7.1

Hello. I've come across a weird compiler warning when using the regex library on VC 7.1 (I think the problem also occurs in VC 7.0). I'm using Boost 1.33.1 The code below throws up warnings. Removing the min() call from main, or changing a, b and c's type to anything else (e.g. short) gets rid of the warnings. The offending line is in regex_format.hpp (it appears twice in that file): std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), ::boost::re_detail::distance(m_position, m_end)); Putting a static cast around the distance() call makes no difference, but splitting it into two lines as follows gets rid of the warning: std::ptrdiff_t distance = ::boost::re_detail::distance(m_position, m_end); std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), distance); This makes absolutely no sense to me! My code and the warnings are below. #include "boost/regex.hpp" #include <iostream> #include <string> int main(int argc, char *argv[]) { std::string hello = "hello world!"; boost::regex multipleSpacesRegex("([[:space:]]){2,}"); int a=1, b=2; // Remove the next line to get rid of the warnings int c=(std::min)(a,b); hello = boost::regex_replace(hello, multipleSpacesRegex, "$1"); std::cout << hello << std::endl; return 0; } ------ Build started: Project: regex_test, Configuration: Debug Win32 ------ Compiling... main.cpp f:\dev\include\boost\regex\v4\regex_format.hpp(246) : warning C4244: 'argument' : conversion from 'std::iterator_traits<_Iter>::difference_type' to 'const int', possible loss of data with [ _Iter=const char * ] f:\dev\include\boost\regex\v4\sub_match.hpp(130) : while compiling class-template member function 'void boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::format_perl(void)' with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\vector(152) : while compiling class-template member function 'void boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::format_all(void)' with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xstring(542) : while compiling class-template member function 'boost::re_detail::string_out_iterator<S> boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::format(const boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::char_type *,const boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::char_type *,boost::regex_constants::match_flag_type)' with [ S=std::basic_string<char,std::char_traits<char>,std::allocator<char>>, OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] f:\dev\include\boost\regex\v4\regex_format.hpp(568) : see reference to class template instantiation 'boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>' being compiled with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] f:\dev\include\boost\regex\v4\match_results.hpp(170) : see reference to function template instantiation 'OutputIterator boost::re_detail::regex_format_imp<OutputIterator,std::basic_string<_Elem,_Traits,_Ax>::const_iterator,std::vector<_Ty>::allocator_type,_Elem,boost::regex_traits_wrapper<BaseT>>(OutputIterator,const boost::match_results<BidiIterator> &,const charT *,const charT *,boost::regex_constants::match_flag_type,const traits &)' being compiled with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char>, _Ty=boost::sub_match<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, BaseT=boost::regex_traits<char>, BidiIterator=std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator, charT=char, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] f:\dev\include\boost\regex\v4\regex_replace.hpp(53) : see reference to function template instantiation 'OutputIterator boost::match_results<BidiIterator>::format<OutputIterator,boost::basic_regex<charT,traits>>(OutputIterator,const boost::match_results<BidiIterator>::st std::ptrdiff_t distance = ::boost::re_detail::distance(m_position, m_end); std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), distance); ring_type &,boost::regex_constants::match_flag_type,const RegexT &) const' being compiled with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, BidiIterator=std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator, charT=char, traits=boost::regex_traits<char>, RegexT=boost::basic_regex<char,boost::regex_traits<char>> ] f:\dev\include\boost\regex\v4\regex_replace.hpp(84) : see reference to function template instantiation 'OutputIterator boost::regex_replace<boost::re_detail::string_out_iterator<S>,std::basic_string<_Elem,_Traits,_Ax>::const_iterator,boost::regex_traits<charT>,char>(OutputIterator,BidirectionalIterator,BidirectionalIterator,const boost::basic_regex<charT,traits> &,const charT *,boost::regex_constants::match_flag_type)' being compiled with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, S=std::basic_string<char,std::char_traits<char>,std::allocator<char>>, _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char>, charT=char, BidirectionalIterator=std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator, traits=boost::regex_traits<char> ] f:\dev\projects\regex_test\main.cpp(17) : see reference to function template instantiation 'std::basic_string<_Elem,_Traits,_Ax> boost::regex_replace<boost::regex_traits<charT>,char>(const std::basic_string<_Elem,_Traits,_Ax> &,const boost::basic_regex<charT,traits> &,const charT *,boost::regex_constants::match_flag_type)' being compiled with [ _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char>, charT=char, traits=boost::regex_traits<char> ] f:\dev\include\boost\regex\v4\regex_format.hpp(330) : warning C4244: 'argument' : conversion from 'std::iterator_traits<_Iter>::difference_type' to 'const int', possible loss of data with [ _Iter=const char * ] f:\dev\include\boost\regex\v4\sub_match.hpp(130) : while compiling class-template member function 'void boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::format_escape(void)' with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] f:\dev\include\boost\regex\v4\regex_format.hpp(401) : warning C4244: 'argument' : conversion from 'std::iterator_traits<_Iter>::difference_type' to 'const int', possible loss of data with [ _Iter=const char * ] f:\dev\include\boost\regex\v4\regex_format.hpp(422) : warning C4244: 'argument' : conversion from 'std::iterator_traits<_Iter>::difference_type' to 'const int', possible loss of data with [ _Iter=const char * ] f:\dev\include\boost\regex\v4\sub_match.hpp(130) : while compiling class-template member function 'void boost::re_detail::basic_regex_formatter<OutputIterator,Results,traits>::format_conditional(void)' with [ OutputIterator=boost::re_detail::string_out_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, Results=boost::match_results<std::basic_string<char,std::char_traits<char>,std::allocator<char>>::const_iterator>, traits=boost::regex_traits_wrapper<boost::regex_traits<char>> ] Linking... Build log was saved at "file://f:\dev\projects\regex_test\Debug\BuildLog.htm" regex_test - 0 error(s), 4 warning(s) ---------------------- Done ---------------------- Build: 1 succeeded, 0 failed, 0 skipped ___________________________________________________________ Yahoo! Photos NEW, now offering a quality print service from just 8p a photo http://uk.photos.yahoo.com

The code below throws up warnings. Removing the min() call from main, or changing a, b and c's type to anything else (e.g. short) gets rid of the warnings.
Oh this just sucks ! I think I know what the problem is, and I've complained to MS before about this to no avail. If you have a bunch of overloaded functions like this: foo(short); foo(int); foo(long); foo(long long); and you call foo with a ptrdiff_t as an argument, then even though the call is always safe (because there is always a correct overload, no matter what the width of ptrdiff_t) then you get a C4244 warning. It happens a lot if you try and send a size_t or ptrdiff_t to an iostream for example. In this case instantiating std::min<int> before the regex code sees it, means that the compiler sees an already instantiated function that takes an int as argument, and so issues the spurious conversion warning. I've no idea why your workaround works, but I've just applied it in a bunch of places to the regex code. Of course there are probably an infinitely sized set of similar gotcha's just waiting to trap the unwary. Thanks for the report, John.
participants (2)
-
Alan Davies
-
John Maddock