
Currently, if you try to compile a program that uses boost::regex (either boost versions 1.31 and 1.32) under the debug static runtime library(libboost_regex-vc71-sgd-1_32.lib), you'll get a bunch of multiply defined symbols something like this: LIBCMTD.lib(_wctype.obj) : error LNK2005: _iswlower already defined in c_regex_traits.obj and so on for all of the character type macros: _iswalpha _iswupper _iswlower _iswdigit _iswxdigit _iswspace _iswpunct _iswalnum _iswprint _iswgraph _iswcntrl _iswascii This has been noticed before && stems from the fact that the inline directive is ignored for debug mode, causing those inline functions to exist both in the C runtime library and in the regex lib. I found a note going back to 2002 - http://lists.boost.org/MailArchives/boost-users/msg01398.php - which indicates that this problem is longstanding. Unfortunately, I'd like to be able to use boost::regex, and I'd like to be able to use static runtime libraries. I doubt I'm the only person who'd like be able to do that. Fortunately, the references to those macros/inlines seems to be localized to only one file, libs\regex\src\c_regex_traits.cpp, so I thought I'd try fixing that file. Digging around a bit, I modified libs\regex\src\c_regex_traits.cpp to compile and link correctly for this model. I attached the diffs below; I'm sure that there was a more elegant way, but at least this is a solution that allows the regex library to link under all runtime libraries for VC7. Maybe somebody could boostify the solution and incorporate this into the next release of the boost libraries? Thanks, Rob. --- diff follows 45a46,65
# ifdef BOOST_MSVC // Workaround for .NET2003 (VC7) linkage problem. // This prevents inline functions from existing in both the static debug multithreaded unicode runtime library and in this library, a problem // which causes link errors like: // LIBCMTD.lib(_wctype.obj) : error LNK2005: _iswlower already defined in c_regex_traits.obj
#define iswalpha(_c) ( iswctype(_c,_ALPHA) ) #define iswupper(_c) ( iswctype(_c,_UPPER) ) #define iswlower(_c) ( iswctype(_c,_LOWER) ) #define iswdigit(_c) ( iswctype(_c,_DIGIT) ) #define iswxdigit(_c) ( iswctype(_c,_HEX) ) #define iswspace(_c) ( iswctype(_c,_SPACE) ) #define iswpunct(_c) ( iswctype(_c,_PUNCT) ) #define iswalnum(_c) ( iswctype(_c,_ALPHA|_DIGIT) ) #define iswprint(_c) ( iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT) ) #define iswgraph(_c) ( iswctype(_c,_PUNCT|_ALPHA|_DIGIT) ) #define iswcntrl(_c) ( iswctype(_c,_CONTROL) ) #define iswascii(_c) ( (unsigned)(_c) < 0x80 ) # endif
520,521c540,545 < lower_case_map[i] = (char)std::tolower(i); < } ---
# ifdef BOOST_MSVC lower_case_map[i] = (char)tolower(i); # else lower_case_map[i] = (char)std::tolower(i); # endif } 915a940,967 # ifdef BOOST_MSVC bool BOOST_REGEX_CALL c_regex_traits<regex_wchar_type>::do_iswclass(regex_wchar_type c, boost::uint_fast32_t f) { BOOST_RE_GUARD_STACK if((c & ~0xFF) == 0) return BOOST_REGEX_MAKE_BOOL(re_detail::wide_unicode_classes[(uchar_type)c] & f); if((f & char_class_alpha) && iswalpha(c)) return true; if((f & char_class_cntrl) && iswcntrl(c)) return true; if((f & char_class_digit) && iswdigit(c)) return true; if((f & char_class_lower) && iswlower(c)) return true; if((f & char_class_punct) && iswpunct(c)) return true; if((f & char_class_space) && iswspace(c)) return true; if((f & char_class_upper) && iswupper(c)) return true; if((f & char_class_xdigit) && iswxdigit(c)) return true; if(f & char_class_unicode) return true; return false; }
#else 940a993 # endif // BOOST_MSVC