Why Is Std::Min Failing When Windows.H Is Included

Why is std::min failing when windows.h is included?

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).

How do I deal with the max macro in windows.h colliding with max in std?

Define the macro NOMINMAX:

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

Why does std::numeric_limits long long ::max() fail?

That max call may interfere with "evil" max preprocessor macro defined in the Windows SDK headers, that you have probably included (directly or indirectly).

An option is to prevent the preprocessor max macro to kick in, using an additional pair of parentheses:

... = (std::numeric_limits<long long>::max)();

As an additional option, you may consider #define #NOMINMAX before including Windows headers. This will prevent the definition of the aforementioned min and max preprocessor macros.

However, note that some Windows headers (like the GDI+ ones) do require the Win32's min and max preprocessor macros, so in such cases the use of an additional pair of parentheses may be a better option.

Illegal token on right side of ::

My guess is that max has been made a macro. This happens at some point inside windows.h.

Define NOMINMAX prior to including to stop windows.h from doing that.

EDIT:

I'm still confident this is your problem. (Not including <limits> would result in a different error). Place #undef max and #undef min just before the function and try again. If that fixes it, I was correct, and your NOMINMAX isn't being defined properly. (Add it as a project setting.)

You can also prevent macro expansion by: (std::numeric_limits<T>::max)().


On a side note, why not do std::numeric_limits<T>::min() instead of negating the max?

#define NOMINMAX using std::min/max

If you're really desperate, put parentheses around the function names:

(std::min)(x, y);

This syntax won't apply a function-like macro. (Formally, to apply a function-like macro the name of the macro must be followed by optional white space then a '('.)

Why doesn't std::abs() works with floats

You have to be very careful when using the overloads of std::abs as some standard library implementations litter the overloads across many files, some of which get implicitly included into others, like <iostream>.

If you #include <cmath> or #include <cstdlib> (the second one from C++17) before your std::abs(0.5f) then the float overload will be available. If that's not the case, then there is a bug in your compiler / standard library implementation (unlikely in the case of g++).

Reference: https://en.cppreference.com/w/cpp/numeric/math/fabs

Why am I getting the error WM_MENUCOMMAND was not declared in this scope when I included windows.h?

WM_MENUCOMMAND is defined in winuser.h (which windows.h includes), but only when WINVER is >= 0x0500 and _WIN32_WCE is not defined. So you likely have WINVER set too low. It is set to 0x0500 by default, so something in your project must be redefining it to a lower value.



Related Topics



Leave a reply



Submit