83

So I was trying to get valid integer input from cin, and used an answer to this question.

It recommended:

#include <Windows.h> // includes WinDef.h which defines min() max()
#include <iostream>
using std::cin;
using std::cout;

void Foo()
{
    int delay = 0;
    do
    {
        if(cin.fail())
        {
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        cout << "Enter number of seconds between submissions: ";
    } while(!(cin >> delay) || delay == 0);
}

Which gives me an error on Windows, saying that the max macro doesn't take that many arguments. Which means I have to do this

do
{
    if(cin.fail())
    {
        cin.clear();
#undef max
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    cout << "Enter number of seconds between submissions: ";
} while(!(cin >> delay) || delay == 0);

To get it to work. That's pretty ugly; is there a better way to work around this issue? Maybe I should be storing the definition of max and redefining it afterward?

Community
  • 1
  • 1
Almo
  • 15,538
  • 13
  • 67
  • 95
  • 7
    Do You include ? Why? If You really need it you can avoid define of _min_ and _max_ macros by defining **NOMINMAX** before including it. – Piotr Tkaczyk Jul 18 '12 at 14:50
  • 1
    Are you using "namespace std"? If so, you are deliberately combining namespaces. – Paul Beckingham Jul 18 '12 at 14:51
  • 8
    @PaulBeckingham: macros have no namespaces, and thus including windows.h without any precautions will always collide with `std::min`/`std::max` – PlasmaHH Jul 18 '12 at 15:00
  • 1
    possible duplicate of [Strange C++ errors with code that has min()/max() calls](http://stackoverflow.com/questions/14165/strange-c-errors-with-code-that-has-min-max-calls) – PlasmaHH Jul 18 '12 at 15:03
  • check http://stackoverflow.com/questions/1394132/macro-and-member-function-conflict – Mr. Ree Dec 27 '14 at 08:39

6 Answers6

124

Define the macro NOMINMAX:

This will suppress the min and max definitions in Windef.h.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 6
    For some reason the url does not work for me, even though it is returned as only hit for: https://support.microsoft.com/en-us/search?query=NOMINMAX – malat Nov 20 '19 at 14:47
97

Just wrap the function name in parenthesis:

(std::numeric_limits<size_type>::max)()

No need for the NOMINMAX macro in this case, plus you won't get compiler warnings

NIRO
  • 979
  • 6
  • 2
  • 2
    `std::max(a,b)` works for me and is more readable. The template parameter suppresses the macro. Am I missing something? – Dale Wilson Feb 03 '17 at 22:02
  • 4
    @DaleWilson Yes, you're missing something. Your call will get the larger of two values. std::numeric_limits::max() will return the maximum value that can be stored by size_type. – Ben Apr 25 '17 at 18:08
  • 2
    Wrapping the function name in parens is taking the function pointer & invoking it as though implementing a strategy pattern via function pointers. That defies the advice of [expressing ideas directly in code](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#p1-express-ideas-directly-in-code) since this other syntax is rather an attempt to work around the definition of the min & max macros (not an implementation of strategy pattern via function pointer). The Clang/LLVM infrastructure suggests "`#define NOMINMAX` before any Windows header". Which is better advice IMO. – Louis Langholtz Sep 03 '17 at 16:01
  • 2
    @LouisLangholtz With VS projects there is common stdafx.h and when you place NOMINMAX in it, there can be errors in other files, which use the macros. – ggurov Jul 30 '18 at 12:37
  • 1
    When working with a project that includes legacy code (which might use the old max and min macros), this is your best option. The ugly syntax is a trade-off. – jakar Dec 07 '18 at 16:52
  • 1
    FTR, I believe `std::numeric_limits::max ()` (with an extra space) also works. But I'd recommend just defining `NOMINMAX`. – celticminstrel Aug 23 '19 at 19:04
  • 1
    Genius-level solution. This is the best answer in contexts that involve other libraries etc... – atlex2 Sep 15 '21 at 15:39
13

If you don't know whether somebody else might have included windows.h without NOMINMAX, you might define a dummy macro which can be used to suppress function-like macro invocations without changing the definition:

#define DUMMY
...
std::numeric_limits<std::streamsize>::max DUMMY ()

Not really pretty either, but works and is non-intrusive.

When working with the Windows header file, I prefer to hide it as much as I can by including it only in specialized code and header files (using pimpl if necessary), because it throws just too much garbage into the global namespace.

Philipp
  • 48,066
  • 12
  • 84
  • 109
  • 3
    Interesting. I will definitely be following advice to peel out windows.h wherever possible. – Almo Jul 18 '12 at 21:53
  • This is an excellent way to do things when writing a header for use by others and you cannot control whether the user #includes windows.h before your header – Phil Rosenberg Jan 12 '21 at 13:31
11

Are you just trying to flush the cin buffer? I always just used:

cin.ignore(cin.rdbuf()->in_avail());
Littlegator
  • 385
  • 4
  • 18
  • This is a good answer, though I have accepted the other one as it directly answers the question, while yours addresses the source of the problem in another way. :) – Almo Jul 18 '12 at 15:07
7

If you happen to use GDI+, the approach with NOMINMAX won't work for you, because headers of GDI+ require min or max in global namespace.

And the simplest workaround in this case is to undefine min/max when they are no longer needed.

The code sample to illustrate the approach:

//#define NOMINMAX - this won't work
#include <Windows.h>
#include <gdiplus.h>
#undef max
#undef min
...
#include <cxxopts.hpp>
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
AntonK
  • 1,210
  • 1
  • 16
  • 22
  • 1
    Potentially reverses the problem, though: if name clash happens in a header, solved as described here, and you include the this header somewhere requiring min/max yet to be defined - bad luck... – Aconcagua Jan 31 '18 at 13:11
2

I came here looking for a list of common things that windows.h defines, and after much scouring, I found min, max, small, near, far. Hopefully this helps someone else, too.

I realize this question is 10 years old, but nobody answered with the obvious solution, so here's my way of dealing with this issue.

All OS specific stuff goes in one translation unit (one CPP source file) which provides a cleaner API to the rest of the project, and thus windows.h never pollutes the rest of the project. Any handles to OS stuff is just a "NativeHandle" which is typedef'd to void*; some things are heap allocated this way that wouldn't otherwise need to be possibly, but that's not much of a downside, considering this also provides a single source point for porting to other platforms.

Jimmio92
  • 321
  • 2
  • 9