std::min and std::max
Today I typed the following:
Why did I put parentheses around std::max? Because windows.h defines (among other things) a max and a min macro. If you include windows.h the above code will not compile. For example the following:
Will produce the following error with Visual Studio C++ 2005:
There are a number of ways to work around windows.h defining these two macros.
int t = (std::max)(timeout, lagtime);
Why did I put parentheses around std::max? Because windows.h defines (among other things) a max and a min macro. If you include windows.h the above code will not compile. For example the following:
#include "windows.h"
#include <algorithm>
void foo() {
int i = 5;
int j = 7;
int x = std::max(i,j);
}
Will produce the following error with Visual Studio C++ 2005:
1>test.cpp(7) : error C2589: '(' : illegal token on right side of '::'
1>test.cpp(7) : error C2143: syntax error : missing ';' before '::'There are a number of ways to work around windows.h defining these two macros.
- Use alternative names defined in windows.h.
int x = _cpp_max(i,j);
This is not portable; only works on Windows.
int y = _cpp_min(i,j); - Define NOMINMAX before including windows.h. This might break existing code that assumes NOMINMAX is not defined.
- Don't use std::min and std::max. Instead use the tertiary operator like so:
int x = i > j ? i : j; // max(i,j)
This is portable but not as readable and more error prone.
int y = i < j ? i : j; // min(i,j) - Use using statements to make the code portable:
using std::min;
This works but requires two more lines of code. You could also just use 'using namespace std;' but that might pull in more than you want.
using std::max;
int x = max(i,j);
int y = min(i,j); - Use std::min<int> and std::max<int>
int x = std::max<int>(i,j);
This requires you to specify the type. However in some cases this actually helps. For example:
int y = std::min<int>(i,j);int i = 5;
Note the 'unsigned'. Generates the following errors:
unsigned int j = 7;
int x = (std::max)(i,j);
int y = (std::min)(i,j);1>test.cpp(7) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' :
By explicitly specifying type via <int> you remove the ambiguity.
expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 8\vc\include\xutility(3190) :
see declaration of 'std::max'
1>test.cpp(7) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' :
template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 8\vc\include\xutility(3182) :
see declaration of 'std::max'
1> could be 'unsigned int'
1> or 'int' - Use (std::min) and (std::max)
int i = 5;
This works (as does the std::max<int>) because the C++ preprocessor requires '(' as the next preprocessing token following the macro name to preform the macro expansion.
int j = 7;
int x = (std::max)(i,j);
int y = (std::min)(i,j);
Labels: C++, Visual Studio

6 Comments:
I usually just #undef min/max after including windows.h. At least that's how I remember it, although it's been several years since I was a c++ programmer. :(
Thank you for reporting this. I am new to Windows programming. I had this error and I was very confused. I want to write portable code, and this article describes many options available.
Great article.
Thanks for these solutions. Without this article I probably wouldn't have found the origin of this compile error.
Thank you. This was really helpful!
another possibility to trick the preprocessor ist the insertion of an empty macro.
But this also reads not very nice.
#define ____
std::max ____ (a,b)
Post a Comment
<< Home