std::max - expected an identifier
Asked Answered
B

6

48

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?

Betweenwhiles answered 12/8, 2011 at 2:26 Comment(4)
Have you included <algorithm>? Are you including <windows.h>?Academia
OP sez: "I've included the algorithm standard header."Havstad
Can you include a full example we can try to compile? Your program is short enough for that.Firstborn
Unrelated, but it seems like it'd be shorter and easier to read if you wrote std::max(myInt, myOtherInt) + 2 * border;Rotenone
K
92

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.

Kennie answered 12/8, 2011 at 2:41 Comment(5)
It looks like it compiles when I add this. But why? Is this a bug?Betweenwhiles
@Jay: apparently it's <windows.h> itself that messes everything up by defining macros named min and max. Congrats to Microsoft! More here.Amazement
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 <class T> 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.Betweenwhiles
Maybe other standard headers include Windows.h because none of my header files are!Betweenwhiles
@Betweenwhiles : If you're using MFC, or any other GUI framework, then windows.h will invariably be included somewhere.Kennie
E
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)

Emplace answered 12/8, 2011 at 2:44 Comment(1)
Wow this is awesome! Just what I was looking for. I was trying to use std::numeric_limits<uint32_t>::max() and the stupid windows.h was causing the preprocessor to insert std::max() in place of max(). Simply doing (std::numeric_limits<uint32_t>::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!Hornbill
T
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>.

Taphouse answered 12/8, 2011 at 2:29 Comment(0)
W
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.

Waltz answered 11/11, 2013 at 18:57 Comment(0)
M
1

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]

Maulstick answered 25/9, 2022 at 8:5 Comment(2)
"Just a brief collection of other answers"... why? This doesn't add any value imhoMuck
@Muck 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 ;-)Kianakiang
A
0

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

Amazement answered 12/8, 2011 at 2:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.