#define NOMINMAX using std::min/max - c++

i recently added:
#define NOMINMAX
#include <Windows.h>
#include <algorithm>
to my main.cpp in order to use
std::max( x , x ); // x is just a placeholder and not actual anything
std::min( x , x );
but i can't use std::max()/std::min() in other files.
error C2589: '(' : illegal token on right side of '::'
error C2059: syntax error : '::'
i tried to add #define NOMINMAX in my other files, but fails. what is the clue?
i looked around before asking, but i don't understand the answer Possible problems with NOMINMAX on Visual C++

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

Define NOMINMAX via a compiler flag:
> cl.exe -DNOMINMAX ...
this will then be defined for all of the source files. I don't use the IDEs but this page provides guidance on navigating the IDE to set this: Using STL in Windows Program Can Cause Min/Max Conflicts
:
Simply define the NOMINMAX preprocessor symbol. This can be done in the Developer Studio project under Build, Settings, on the C/C++ tab, in the Preprocessor category. This will suppress the min and max definitions in Windef.h.

If you define NOMINMAX, because you prefer the STL version, then you may get problems while including gdiplus.h, which uses the min/max macro.
As solution you need to include the STL headers and use "using namespace std" before you include the gdiplus.h.
In example:
#define NOMINMAX
// Include C++ headers
#include <algorithm>
using namespace std;
// Include Windows headers
#include <windows.h>
#include <gdiplus.h>

It's likely that your problem is that you #define NOMINMAX after you #include "windows.h". It is important that the #define come first.
The reason is that windows.h (actually I think windef.h, which is included by windows.h) has code similar to this:
#ifndef NOMINMAX
#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
So #define NOMINMAX is telling the compiler (or actually the preprocessor) to skip over the definitions of min and max, but it will only apply if you do it before you #include "windows.h".

In Visual Studio, Adding 'NOMINMAX' to C++ preprocessor properties fixed my issue.
Open project properties -> C/C++ -> Preprocessor -> Preprocessor Definitions -> Add 'NOMINMAX'.

Related

SpriteBatch and SpriteFont (DirectXTK) throw an error (expected unqualified-id)

I'm using clang++ that links to MSVC.
I compiled shaders (DirectXTK\Shaders) and included SpriteBatch and SpriteFont in my source code.
If I include just the header files (.h), I get linking errors; if I include source files (.cpp; with or without .h), I get this:
SpriteBatch.cpp:532:27: error: expected unqualified-id
size_t newSize = std::max(InitialQueueSize, mSpriteQueueArraySize * 2);
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\minwindef.h:193:29: note: expanded from macro 'max'
#define max(a,b) (((a) > (b)) ? (a) : (b))
I tried to find the solution on the GitHub issues page of DirectXTK, on this website and on the web, but didn't find anything helpful.
The Windows headers define a 'min' and 'max' macro that interacts poorly with std::min/std::max from <algorithm>.
In all my templates and tests, I define NOMINMAX before using Windows.h to avoid this problem. It's generally a better practice. If you still need to use a macro form while doing this, you can use __min/_max.
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define NODRAWTEXT
#define NOGDI
#define NOBITMAP
#define NOMCX
#define NOSERVICE
#define NOHELP
#include <Windows.h>
See this other thread and this blog post

visual c++ min max warning when including armadillo library

I use the armadillo library in visual C++ to take care of some matrix and vector operations. Here's what one of my cpp files looks like:
#include "stdafx.h"
#include <cmath>
#include <armadillo>
#include "buildRotMatrix.h"
using namespace std;
using namespace arma;
//code
When I compile I get the following warning:
1>CL : warning : detected 'min' and/or 'max' macros and undefined them;
1>CL : warning : you may wish to define NOMINMAX before including any windows header
I don't actually use min and max functions in the code but i'd like to get rid of the warnings. adding #define NOMINMAX hasn't worked and I haven't found other solutions. It's not clear to me where the conflict comes from since my understanding from google searches is people get it from including windows.h.

Define from include breaking other previous includes

I'm trying to debug the includes of my project's main file. Here's my include code.
//Gameplay
#include "gameplay.h"
//LibNoise
#include <noise/noise.h>
//Console Window
#ifndef _WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef KEY_EVENT
#undef MOUSE_EVENT
#endif
#include <io.h>
#include <fcntl.h>
//RakNet
#include "MessageIdentifiers.h"
#include "RakPeerInterface.h"
#include "BitStream.h"
#include "RakNetTypes.h"
//My Includes
#include "Island.h"
The problem is, gameplay.h includes a file (specifically ScriptController.h) where there's an enum that contains the words KEY_EVENT and MOUSE_EVENT which is included through some includes in windows.h (specifically wincon.h). This breaks the enum and I get errors during compilation. Note, it is actually including windows.h because _WINDOWS_ isn't defined at this point according to MSVS (so it's not like it's defined before gameplay.h or something).
I can't see why this would be a problem as gameplay.h is included before windows.h which should mean that I would get no trouble with replacement of the terms in the enum? Undefining them doesn't help either.
Where did I go wrong? Is there any way I can "debug" the preprocessor and see the output from the preprocessor that is causing this syntax error and some kind of #include chain? I want to be able to fix this myself next time if it occurs.
Here's the errors
Error 3 error C2065: 'CALLBACK_COUNT' : undeclared identifier c:\users\pf\downloads\gameplay-master\gameplay\src\scriptcontroller.h 1024 1 testerino2
Error 1 error C2059: syntax error : 'constant' c:\users\pf\downloads\gameplay- master\gameplay\src\scriptcontroller.h 769 1 testerino2
Error 2 error C3805: 'constant': unexpected token, expected either '}' or a ',' c:\users\pf\downloads\gameplay-master\gameplay\src\scriptcontroller.h 769 1 testerino2
Here's the wincon.h defines
#define KEY_EVENT 0x0001 // Event contains key event record
#define MOUSE_EVENT 0x0002 // Event contains mouse event record
Here's the offending code lines of ScriptController.h
762| enum ScriptCallback
763| {
764| INITIALIZE = 0,
...
768| RESIZE_EVENT,
769| KEY_EVENT,
770| MOUSE_EVENT,
771| TOUCH_EVENT,
...
775| GAMEPAD_EVENT,
776| CALLBACK_COUNT,
777| INVALID_CALLBACK = CALLBACK_COUNT
778| };
...
1024| std::vector<std::string> _callbacks[CALLBACK_COUNT];
To avoid clashes with windows.h defines, I'd recommend making your own header file that:
Defines any macros that affect windows.h, such as WIN32_LEAN_AND_MEAN
Does #include <winsock2.h> if used, and #include <windows.h>
Does #undef on any annoying macros
Then make sure every source file that might come across a Windows include, includes this header. You could perhaps use a compiler feature to inject the header into all units.

Qt Creator's intellisense thinks that min and max were defined even though they weren't

In my code I have
#define NOMINMAX
#include <windows.h>
But whenever I use std::max or std::min the intellisense underlines the line with red, even though the compiler does not complain about it. If I change the code to
#define NOMINMAX
#include <windows.h>
// make sure they min/max weren't defined
#if defined(min) || defined(max)
#error "min or max were defined"
#endif
// but intellisense still thinks they were,
// so this is needed
#undef min
#undef max
the problem disappears. But defining NOMINMAX prevents windows.h from defining min/max, so why is intellisense thinking that they were defined, even though they were not? And I've checked, the preprocessor error I've added is never hit.
Actually, I did not uninstall it. It helps to sort out indexer if I add DEFINES+=NOMINMAX
...and then CLOSE and RE-OPEN the project. Even though QtCreator told 'Parsing' after every change to .pro file I did not see immediate effect. Looks like if you re-open the project it does better 'Parsing'
My QtCreator version is 2.6.1 and I use Qt5.0.0

How can I #include a file whose name is built up from a macro?

On a cross-platform project, I want to #include a header file whose name contains the name of the platform. I have a #define macro for the platform.
So for example, for
#define PLATFORM win32
I want
#include "engine\win32\devices_win32.h"
while for
#define PLATFORM linux
I want
#include "engine\linux\devices_linux.h"
I'm going with Richard Pennington's answer, minus one line of code - it works for me!
#define PLATFORM Linux
#define xstr(x) #x
#define str(x) xstr(x)
#define sub(x) x
#include str(sub(engine/PLATFORM/devices_)PLATFORM.h)
Usually, you would do something more like:
#ifdef WIN32
#include "devices_win32.h"
#endif
#ifdef LINUX
#include "devices_linux.h"
#endif
...rather than having a single PLATFORM definition which can be set differently depending on the platform.
#define PLATFORM Linux
#define xstr(x) #x
#define str(x) xstr(x)
#define sub(x) x
#define FILE str(sub(engine/PLATFORM/devices_)PLATFORM.h)
#include FILE
I'm not sure I'd use it, though. ;-)
I had to use Linux rather than linux because linux is defined as 1 in my compiler.
Well in practice, this could be achieved using something like
#define PLATFORM win32
#define INCLUDE_FILE devices_ ## PLATFORM
#define QUOTED_INCLUDE_FILE #INCLUDE_FILE
#include QUOTED_INCLUDE_FILE
but the the following rule would prevent you from doing this:
C comments and predefined macro names are not recognized inside a #include' directive in which the file name is delimited with <' and `>'.
C comments and predefined macro names are never recognized within a character or string constant. (Strictly speaking, this is the rule, not an exception, but it is worth noting here anyway.)