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);
13 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)
Thank you. It is very useful. :)
Thanks! I too try to write portable code. I added windows.h at a later time in my program for one test platform which caused the errors that never showed up previously. Thanks to your article, I was able to quickly resolve the issue.
I'm normally a Linux programmer and this compiler error had me going for a full day - damn MS!
Thanks for the solution!
Very helpful, thanks!
#undef works fine.Thanks
As solution, I would suggest switching to a standard compliant compiler.
Oh God... This 2008 article helps a Chinese programmer today. Thanks man!
Post a Comment