47

I'm having a problem with std::max. I can't figure it out.

int border = 35;
int myInt = 2;
int myOtherInt = 3;
int z = std::max(myInt + 2 * border, myOtherInt + 2 * border);

I've included the algorithm standard header. When I mouse over max, I am getting:

Error: expected an identifier

And a compile errors of:

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

What is wrong?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Jay
  • 473
  • 1
  • 4
  • 4

6 Answers6

86

Hazarding a guess, since you're using VC++ – put this before any #includes:

#define NOMINMAX

windows.h defines macros named min and max like so:

#define min(a,b)            (((a) < (b)) ? (a) : (b))
#define max(a,b)            (((a) > (b)) ? (a) : (b))

The Windows SDK has contained these macros since before C++ was standardized, but because they obviously play havoc with the C++ standard library, one can define the NOMINMAX macro to prevent them from being defined.

As a rule, if you're using C++ (as opposed to C) and including windows.h, always define NOMINMAX first.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • 1
    It looks like it compiles when I add this. But why? Is this a bug? – Jay Aug 12 '11 at 02:44
  • 3
    @Jay: apparently it's `` itself that messes everything up by defining macros named `min` and `max`. Congrats to Microsoft! More [here](http://stackoverflow.com/questions/4913922/possible-problems-with-nominmax-on-visual-c/4914108#4914108). – jweyrich Aug 12 '11 at 02:49
  • Thanks for the explanation. The way I understand it, Windows.h defines those macros. And then somewhere in the C++ standard library, in the namespace std, the function template T max(const T& x, const T& y) is defined. So when it comes to this line, there is confusion over the max macro and the generic function max. The only odd thing is if I don't include Windows.h (so the conflict shouldn't occur) I still can't use std::max. – Jay Aug 12 '11 at 03:13
  • Maybe other standard headers include Windows.h because none of my header files are! – Jay Aug 12 '11 at 03:16
  • @Jay : If you're using MFC, or any other GUI framework, then `windows.h` will invariably be included somewhere. – ildjarn Aug 12 '11 at 04:14
24

If you're on VC++, you can either use #define NOMINMAX prior to including any headers, or do (std::max)(myInt + 2 * border, myOtherInt + 2 * border)

Dave S
  • 20,507
  • 3
  • 48
  • 68
  • 4
    Wow this is awesome! Just what I was looking for. I was trying to use `std::numeric_limits::max()` and the stupid windows.h was causing the preprocessor to insert std::max() in place of `max()`. Simply doing `(std::numeric_limits::max)()` is enough to throw off the preprocessor from doing the wrong thing. I didn't want to do the NOMINMAX thing because I worry windows.h might get included before it is defined, not to mention a lot of my own files include windows.h. Thank you! – PolyMesh Jan 24 '14 at 11:04
4

I would say that either max is #define's to something else or you need to explicitly invoke the template via std::max<int>.

Jim Buck
  • 20,482
  • 11
  • 57
  • 74
2

The "using" declaration (see using Declaration) is yet another way to work around the issue:

int border = 35;
int myInt = 2;
int myOtherInt = 3;
using std::max;
int z = max(myInt + 2 * border, myOtherInt + 2 * border);

It allows using std::max without explicit qualification.

PeterN
  • 29
  • 2
0

Have you tried using ::std::max instead? If this doesn't work, something is messing with your std namespace.

jweyrich
  • 31,198
  • 5
  • 66
  • 97
0

Just a brief collection of other answers.

If max(a,b) is already #defined, (by including windows.h or some Windows-related project, etc.)

  1. #define NOMINMAX
  2. #undef max
  3. (std::max) - Use parentheses to prevent function-like macro1)
  4. std::max<int> - Explicitly give a type for the template.

Precaution: If some part of the project depends on the min/max macro, e.g. using MFC, then just simply doing #define NOMINMAX can cause some problem.

Maybe #undef NOMINMAX should be needed, e.g.:

// just an example
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
// ...

(For more info, please take a look at the answers of this question.)


1) Function-like macros only expand when the next thing after is an opening parenthesis. When surrounding the name with parentheses, the next thing after the name is a closing parenthesis, so no expansion occurs. [ref]

starriet
  • 2,565
  • 22
  • 23
  • _"Just a brief collection of other answers"_... why? This doesn't add any value imho – JHBonarius Sep 25 '22 at 08:28
  • @JHBonarius Please read until the end. I mentioned the precaution :) Also, there are lots of SO answers that puts together diverse answers and some people find it's helpful. I apologize if this answer consumed your precious time ;-) – starriet Sep 25 '22 at 08:38