The min/max problem in C++ and Windows

I'm Michael Suodenjoki - a software engineer living in Kgs. Lyngby, north of Copenhagen, Denmark. This is my personal site containing my blog, photos, articles and main interests.

Updated 2013.11.26 22:24 +0100

 

The min/max problem in C++ and Windows

I recently discovered that a Windows header file - specifically the WinDef.h - defines two macros min and max which may result in conflicts and compiler errors.

You'll hit compiler errors such as:

error C2589: '(' : illegal token on right side of '::'

Any C++ source code including the Windows header will likely head into problems if min or max are used together with the Standard C++ library functions std::min()/std::max() as defined in <algorithm>.

The issue is that using a macro definition for such common names is a bad idea and the min/max problem itself has been there for several years (a Google search can confirm that). So the Windows header should never had defined these macros.

Note: It beats me why Microsoft haven't changed WinDef.h years ago. Also as the min/max are macros they should have been more clearly marked as such - using the common syntactic practice of using MIN/MAX in uppercase.

Note: You should note that Microsoft also have the __min()/__max() C functions as declared in Visual C++'s <stdlib.h> (for C old-stylers) or <cstdlib> (For C++ coolers). These can be used as alternatives, but you should really prefer using std::min() and std::max() because these are part of the C++ standard. Remember that Microsoft prefixes non standard structures and functions with underscore '_' character.

Solution

The solution is one or several of the following (prioritized with best approach first):

  1. Convert your source code to use the Standard C++ std::min() and std::max() and ensure that you #include <algorithm>. Use
    #include <algorithm> 
    using namespace std;
    
    // use min() instead of std::min()
    // use max() instead of std::max()
  2. Define the NOMINMAX macro to instruct WinDef.h not to define the min/max macros. E.g. you can update your Visual C++ compiler options with /D NOMINMAX or you can insert #define NOMINMAX.
  3. Redefine min/max in the specific problematic files. Especially this may be needed in you include gdiplus Windows headers files, because these uses the Windows min/max macros.
  4. 
    #include <algorithm> 
    
    #ifndef max
    #define max(a,b) (((a) > (b)) ? (a) : (b))
    #endif
    #ifndef min
    #define min(a,b) (((a) < (b)) ? (a) : (b))
    #endif
    
    #include <gdiplus.h>
    #undef max
    #undef min
    
    using namespace std;
  5. Alternatively redefine min/max to use use the Visual C++ non-standard __min()/__max(). But min/max are still defined as macros and will likely lead to problems. Not a good solution.
    #ifndef max
    #define max __max
    #endif
    #ifndef min
    #define min __min
    #endif
  6. Alternatively use Visual C++ compiler options /Dmin=__min / Dmax=__max. This will tell compiler and WinDef.h not to define min/max macros and use __min() and __max() functions instead as defined in <cstdlib> (or <stdlib.h>) so ensure this is included. But min/max are still defined as macros and will likely lead to problems. Not a good solution.

More (updated November 26th 2013):