Boost logo

Boost :

From: Ed Brey (brey_at_[hidden])
Date: 2000-07-05 08:32:53


From: "Mark Rodgers" <mark.rodgers_at_[hidden]>

> I have some code that uses std::min and std::max. Of course it doesn't
> work with MSVC. The work around I have used is
>
> #if defined(BOOST_MSVC) && _MSC_VER <= 1200 && !defined(NOMINMAX)
> # undef min
> # undef max
> # define NOMINMAX
> namespace std
> {
> template<class T> inline const T &max(const T &x, const T &y)
> { return x < y ? y : x; }
> template<class T> inline const T &min(const T &x, const T &y)
> { return y < x ? y : x; }
> }
> #endif

There is no perfect solution to this problem, but we can come close. Here
are some issues.

1. You need to give the standard library a chance to define min and max
correctly first; otherwise, it might provide redefinitions. For instance
STLport by default stomps the macros and provides correct inline functions.
This is easy: #include <algorithm> before the workaround; on a conforming
implementation, that header is required anyway.

2. There are some M$ (e.g. atlcom.h) and third-party code that expect to see
min and max in the global namespace. This is easy to fix with a "using
std::min;" from the global namespace. This techically can violate the ODR,
but, IFAIK, there isn't any code out there for which this compiles that ends
up with an observable difference from what the macro would have produced.

3. Here's the tricky part. I've run into some third-party code that
compiles with the min/max macros but not the functions, due to ambiguities
over what type to choose for T. I don't know of any workaround for this. I
believe that this kills the idea of an invisble, out-of-the box relacement;
we must do header mucking with care.

There are a few solutions that should be perfectly safe.

1. Require the user use STLport. This providers a working std::min and
std::max out of the box, and forces the user to have already implemented a
workaround for code that expects min/max macros.

2. Another is to apply the macro fix before using min and max and then undo
it afterward, so the macros get turned back on. (I'm a little rusty on my
preprocessor rules, but I think this would work.)

3. In the section of the code where min and max would be used, #ifdef in the
specific code like "y < x ? y : x" to work around the problem. This would
be equivalent to how member constants that are initialized when they are
declared are repalced with enums for VC.

Another reasonable approach is to go ahead and implement the work-around,
and document that code expecting the macros may need to be modified. In
most cases, this will work just fine and so can amount the less total effort
than the about 3 options. Plus it has the side benefit that the user will
have a working min/max, which the user may want anyway, even if he doesn't
want STLport. However, due to the potential for problems, even if rare, I
would recommend putting the fix into a separate header that is only included
by the boost libraries that need it, rather than bundling this fix into
config.hpp.


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