Boost logo

Boost :

From: Robert Mathews (rmathews_at_[hidden])
Date: 2005-03-01 16:14:09


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk