138
#include <algorithm>
#include <Windows.h>

int main()
{
    int k = std::min(3, 4);
    return 0;
}

What is windows doing if I include Windows.h? I can't use std::min in visual studio 2005. The error message is:

error C2589: '(' : illegal token on right side of '::'
error C2059: syntax error : '::'
at0S
  • 4,522
  • 2
  • 14
  • 10
hidayat
  • 9,493
  • 13
  • 51
  • 66

10 Answers10

192

The windows.h header file (or more correctly, windef.h that it includes in turn) has macros for min and max which are interfering.

You should #define NOMINMAX before including it.


In fact, you should probably do that even if there were no conflict, since the naive definition of the macro shows why function-like macros are a bad idea:

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

If you invoke that macro with, for example:

int x = 5, y = 10;
int c = max(x++, y--);

then y will not end up with what you expect. For example, it will expand to:

int c = ((x++)>(y--)?(x++):(y--));

That expression (unless undefined behaviour kicks in which would be even worse) will decrement y twice, not something you're likely to expect.

I basically use macros only for conditional compilation nowadays, the other two major use cases of old (symbolic constants and function-like macros) are better handled with more modern language features (real enumerated types and inline function suggestion).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
118

No need to define anything, just bypass the macro using this syntax:

(std::min)(a, b); // added parentheses around function name
(std::max)(a, b);
PolyMesh
  • 2,228
  • 2
  • 20
  • 23
  • 1
    Thank you, this is the solution that worked for me. I am working on a code where I can't simply use NOMINMAX as some part of the code use drawing code from Windows that needs the macros. – Mickaël C. Guimarães May 29 '15 at 19:59
  • 3
    Could you explain why parentheses around magic can defeat the evil macro!? Cool – Chen OT Oct 28 '15 at 05:37
  • 3
    I'm not totally sure about all the magic under the hood, but I believe the macro parser is looking to replace exactly "min(", so "min)(" is ignored by the macro parser. And the function name being wrapped with meaningless ()'s doesn't cause any issues outside of macros. – PolyMesh Oct 28 '15 at 08:50
  • 1
    Neat solution, but doesn't solve for the problem of having a function with the name `min` or `max` (sample use case: implementing a class that fits into the [UniformRandomNumberGenerator](http://en.cppreference.com/w/cpp/concept/UniformRandomNumberGenerator) concept). – Nik Bougalis Dec 08 '15 at 11:54
  • Please see Erik's answer, I think it is a better solution. Less hacky, and clearer. – PolyMesh Jul 28 '16 at 17:24
  • @ChenOT A function-like macro is defined as an identifier immediately followed by a left parenthesis (N3690/16.3/10). `min` followed by `)` breaks this rule, therefore `min` is not expanded. – zdf Nov 25 '16 at 19:03
  • @NikBougalis: You shouldn't be polluting the global namespace with functions like `min` and `max` anyway. If you have to deal with that then you have to scope the include in a namespace or something. – Ed S. Oct 24 '17 at 15:24
  • @EdS., perhaps you ought to look at the link I provided to understand my comment. I was not discussing polluting the global namespace. But a macro for `min` or `max` can mess up other code (e.g. `class`-scoped `min` or `max`) like the ones the C++ standard *specifies* for things like the `UniformRandomBitGenerator` concept. – Nik Bougalis Oct 24 '17 at 15:33
  • This is also an issue if you have any static functions or methods named min() or max(), since the macro expansion disrupts the declarations. Better to use the NOMINMAX solution or undefine them. – DavidJ Jan 19 '18 at 15:33
  • @DavidJ Not sure what you mean, it works the same way. This trick is to avoid macro expansion, it will work on static functions or methods just the same. – PolyMesh Jan 19 '18 at 19:40
  • This is the best solution – Ganesh S Oct 13 '19 at 07:10
  • 1
    To the top sir! – Mokus Aug 12 '22 at 14:37
47

My preferred solution is to make the type explicit like so:

auto k = std::min<int>(3, 4);

This also stops the preprocessor from matching to min and is arguably more readable than the parentheses workaround. One problem with the NOMINMAX solution is when your code gets reused on the next project, you (or someone else) has to start again asking why this 'working' code doesn't compile anymore.

However to answer the actual question why is it failing?

The Windows.h file, includes windef.h which defines the following macros:

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

The preprocessor essentially expands macros by looking for the sequence of chars in your code including an open parentheses, in this case min(. It then does a basic search/replace on your code, so after the preprocessor step your code has become:

int k = std::((3)<(4)?(3):(4));

The compiler step, which only has this modified code to go on, is then failing when trying to compile std::( giving you your error message.

You can also now see how the various fixes/workarounds proposed on this page work:

  1. Defining NOMINMAX prior to including windef.h means these macros won't get defined, and so the compiler can compile std::min.
  2. Putting brackets around std::min means the preprocessor doesn't see the sequence min( anymore, and so leaves it alone.
  3. Putting in the template parameter means that min< also is not a match for the macro.
Erik
  • 812
  • 1
  • 7
  • 15
  • 3
    I agree, this is the best solution. I was just coming back to give another answer when I saw that someone else beat me to it. – PolyMesh Jul 28 '16 at 17:22
28

As others mentioned, the errors are due to min/max macros that are defined in windows header(s). There are three ways of disabling them.

1) #define NOMINMAX before including header, this is generally a bad technique of defining macros in order to affect the following headers;

2) define NOMINMAX in compiler command line/IDE. The bad part about this decision is that if you want to ship your sources, you need to warn the users to do the same;

3) simply undefine the macros in your code before they are used

#undef min
#undef max

This is probably the most portable and flexible solution.

Gene Bushuyev
  • 5,512
  • 20
  • 19
  • 2
    Another issue with option 1 is that it simply does not always work. There might be other windows headers being included elsewhere that actually need it such as gdiplus.h. In that case option 3 might be your only hope. – shawn1874 Apr 11 '14 at 18:32
17

Try something like this:

#define NOMINMAX
#include <windows.h>

By default, windows.h defines min and max as macros. When those are expanded, code that tries to use std::min (for example) will end up looking something like this:

int k = std::(x) < (y) ? (x) : (y);

The error message is telling you that std::(x) isn't allowed.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
6

In my case, project did not include windows.h or windef.h explicitly. It was using Boost. So, I resolved the issue by going to the project Properties -> C/C++ -> Preprocessor, and appending NOMINMAX in the Preprocessor Definitions (VS 2013, VS 2015).

Igor Kustov
  • 3,228
  • 2
  • 34
  • 31
Terry
  • 310
  • 3
  • 9
  • For VS 2015 defining the macro in the file didn't work for me. Defining in the project worked. – qqqqq Mar 17 '17 at 00:35
3

For people including windows.h, put the following in effected headers:

#include windows headers ...

pragma push_macro("min")
pragma push_macro("max")
#undef min
#undef max

#include headers expecting std::min/std::max ...

...

pragma pop_macro("min")
pragma pop_macro("max")

In source files just #undef min and max.

#include windows headers ...

#undef min
#undef max

#include headers expecting std::min/std::max ...
3

To solve this issue I just create header file named fix_minmax.h without include guards

#ifdef max
    #undef max
#endif

#ifdef min
    #undef min
#endif

#ifdef MAX
    #undef MAX
#endif
#define MAX max

#ifdef MIN
   #undef MIN
#endif
#define MIN min

#include <algorithm>
using std::max;
using std::min;

Basic usage is like this.

// Annoying third party header with min/max macros
#include "microsoft-mega-api.h"
#include "fix_minmax.h"

Pros of this approach is that it works with every kind of included file or part of code. This also saves your time when dealing with code or libraries that depend on min/max macros

Inline
  • 2,566
  • 1
  • 16
  • 32
2
#define NOMINMAX

is the trick to suppress the macro definitions of max and min

http://support.microsoft.com/kb/143208

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
1

I'd assume windows.h does define min as a macro, e.g. like

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

That would explain the error message.

sstn
  • 3,050
  • 19
  • 32