What is "minmax.h" in C++? - c++

I've been using #include <minmax.h> in my scripts and using min() and max() as expected. I showed this to someone and they had never seen it before, said it wasn't working for them and asked me why I wasn't including <algorithm> and calling std::min() or std::max().
So my question is basically, why aren't I? I found this in a book on C++: "C++ Design Patterns and Derivatives Pricing". Googling "minmax.h", I find a reference to that very book in the top result, so that even more so makes me think it's something abnormal.
Is anyone able to tell me what this is?

The C++ programming language is accompanied by the C++ Standard Library. There is no <minmax.h> header in the C++ Standard Library. No header in the standard-library has the .h extension. Furthermore, the header is not part of the ported C standard library either, as those headers have the c prefix, like <cmath> (which replaces the C standard-library <math.h> header), <ctime>(which replaces the <time.h> header) when used from the C++ Standard Library.
The std::min and std::max functions are declared inside the <algorithm> header.
That being said, there indeed appears to be some MS header called <minmax.h> inside the C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt folder which defines min and max macros, not functions. But, that is some implementation specific header, and you should be using the standard <algorithm> header instead.

why aren't I?
People do all sort of odd things that they heard about somewhere once, be it in school or that came up as some "solution" that fixed their immediate need (usually under timeline pressure). They then keep doing things the same way because they "work". But I'm glad you stopped for a minute to ask. Hopefully we'll steer you back onto the portable C++ route :)
No, there's no need to use the non-standard minmax.h header. On Windows you need to define the NOMINMAX macro before you include any headers whatsoever, and include <algorithm> right after this macro definition. This is just to free the min and max symbols from being taken over by ill-conceived WINAPI macros. In C++, std::min etc. are in the <algorithm> header and that's what you ought to be using. Thus, the following is portable:
#define NOMINMAX
#include <algorithm>
// other includes
#undef NOMINMAX
// your code here
See this answer for details for Windows.

An ancient reference w.r.t. C++, using ancient compilers, supplying examples using non-standard C++ (e.g. headers such as minmax.h)
Note that the book you are mentioning, C++ Design Patterns and Derivatives Pricing (M.S. Joshi), was first released in 2004, with a subsequent second edition released in 2008. As can be seen in the extract below, the examples in the book relied on successful compilation on ancient compiler versions (not so ancient back in 2004, but still far from recent versions).
Appendix D of the book even specifically mentions that the code examples covered by the book may not be standard-compliant, followed by the pragmatic advice that "[...] fixing the problems should not be hard" [emphasis mine]:
The code has been tested under three compilers: MingW 2.95, Borland 5.5, and Visual C++ 6.0. The first two of these are available for free so you should have no trouble finding a compiler that the code works for. In addition, MingW is the Windows port of the GNU compiler, gcc, so the code should work with that compiler too. Visual C++ is not free but is popular in the City and the introductory version is not very expensive. In addition, I have strived to use only ANSI/ISO code so the code should work under any compiler. In any case, it does not use any cutting-edge language features so if it is not compatible with your compiler, fixing the problems should not be hard.
The compiler releases listed above are very old:
Borland 5.5 was released in 2000,
Visual C++ 6.0 was released in 1998,
GCC 2.95 was released in 1999.
Much like any other ancient compiler it is not surprising that these compilers supplied non-standard headers such as minmax.h, particularly as it seems to have been a somewhat common non-standard convention, based on e.g. the following references.
Gnulib Module List - Extra functions based on ANSI C 89: minmax.h, possibly accessible in GCC 2.95,
Known problems in using the Microsoft Visual C++ compiler, version 6.0:
The MS library does not define the min and max algorithms, which should be found in The workaround we use is to define a new header file, say minmax.h, which we include in any file that uses these functions: [...]
What is the worst real-world macros/pre-processor abuse you've ever come across?:
Real-world? MSVC has macros in minmax.h, called max and min, which cause a compiler error every time I intend to use the standard std::numeric_limits::max() function.
Alternative references for the C++ language
Based on the passage above, the book should most likely be considered primarily a reference for its main domain, quant finance, and not such much for C++, other than the latter being a tool used to cover the former.
For references that are focusing on the C++ language and not its application in a particular applied domain (with emphasis on the latter), consider having a look at:
StackOverfow C++ FAQ: The Definitive C++ Book Guide and List.

Related

How to determine which header files to include?

Say I have the below (very simple) code.
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
This compiles fine on both g++ and clang; however, it fails to compile on MSVC with the following error:
error C2039: 'stoi': is not a member of 'std'
error C3861: 'stoi': identifier not found
I know that std::stoi is part of the <string> header, which presumably the two former compilers include as part of <iostream> and the latter does not. According to the C++ standard [res.on.headers]
A C++ header may include other C++ headers.
Which, to me, basically says that all three compilers are correct.
This issue arose when one of my students submitted work, which the TA marked as not compiling; I of course went and fixed it. However, I would like to prevent future incidents like this. So, is there a way to determine which header files should be included, short of compiling on three different compilers to check every time?
The only way I can think of is to ensure that for every std function call, an appropriate include exists; but if you have existing code which is thousands of lines long, this may be tedious to search through. Is there an easier/better way to ensure cross-compiler compatibility?
Example with the three compilers: https://godbolt.org/z/kJhS6U
Is there an easier/better way to ensure cross-compiler compatibility?
This is always going to be a bit of a chore if you have a huge codebase and haven't been doing this so far, but once you've gone through fixing your includes, you can stick to a simple procedure:
When you write new code that uses a standard feature, like std::stoi, plug that name into Google, go to the cppreference.com article for it, then look at the top to see which header it's defined in.
Then include that, if it's not already included. Job done!
(You could use the standard for this, but that's not as accessible.)
Do not be tempted to sack it all off in favour of cheap, unportable hacks like <bits/stdc++.h>!
tl;dr: documentation
Besides reviewing documentation and doing that manually (painful and time consuming) you can use some tools which can do that for you.
You can use ReSharper in Visual Studio which is capable to organize imports (in fact VS without ReSharper is not very usable). If include is missing it recommends to add it and if it is obsolete line with include is shown in more pale colors.
Or you can use CLion (available for all platforms) which also has this capability (in fact this is the same manufacture JetBrains).
There is also tool called include what you used, but its aim is take advantages of forward declaration, I never used that (personally - my team mate did that for our project).

C++ Hash Deprecation Warning

I am very new to C++ and programming in general and am currently working through Bjarne Stroustrup's Programming: Principles and Practices using C++. I'm consistently receiving the error below
Severity Code Description Project File Line Error C2338 <hash_map> is
deprecated and will be REMOVED. Please use <unordered_map>. You can
define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS to acknowledge that
you have received this warning.
I understand that the header file std_lib_facilities.h using some sort of deprecated function, but is there a way to bypass this? It looks like it wants me to define "_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS" but I'm unsure of how to do that. Any help would be appreciated!!
The warning isn't about "some function" - it's about the whole of stdext. And it's not just hand-wavy, to be discontinued eventually, deprecated: it doesn't ship with 2015.
During the early 00's work was afoot to revise the C++ standard; different compiler vendors, Microsoft included, put proposals before the committee along with prototypes. So they could be tested and evaluated, Microsoft placed implementations of their proposed extensions in stdext.
Eventually the committee chose what they were going to incorporate in that revision and released a Technical Report ("TR1"). Anticipating completion before the end of 2009, this was referred to as "C++0x", and compiler vendors began implementing these features in the tr1 namespace. Finally in 2011 the standard was finalized and we got "C++11" with all its bit and pieces back in std where they belong.
According to Microsoft's proposal, the container would be std::hash_map, but the C++ committee chose to use the term unordered_map. std::map is an ordered container, stdext::hash_map, despite the name, is not.
Microsoft's compiler has been the slowest at getting full C++11 support finished, and the standards committee has since finished a second variation (C++14) and is working on a third (C++17). Microsoft is just-about finishing C++11 in VS2015 and a big chunk of C++14, with a few significant exceptions that are apparently going to be a major problem for the VS compiler (esp constexpr and template variables).
Visual Studio 2015 does not provide stdext - it's gone. This is not one of those "well, it may eventually go away" cases.
stdext is specific to the Microsoft family of compilers, so writing code using stdext:: anything is not portable: http://ideone.com/x8GsKY
The standardized version of the feature you're wanting is std::unordered_map, you should use that. It's essentially the same thing.
There are unresolved bugs in stdext::hash_map.
If you really have to use stdext::hash_map, silence the warning by adding
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
at the top of the stdafx.h I assume your project has, or in your header files before you #include <stdext/...>, or in the solution explorer:
Right click on your project's entry in solution explorer,
Select Properties,
Select Configuration: All Configurations,
Expand the C/C++ tree entry,
Select Preprocessor,
The "Preprocessor Definitions" will probably say <different options>
At the beginning of the "Preprocessor Definitions" entry add _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1; so it reads _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1;<different options>.
(or whatever was there originally should follow the ;)
You can put the define prior to your including of the header generating the warning:
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#include <hash_map>
You can also add the symbol in Proprocessor Definitions of the project file.
The later looks prettier, but given your doing something against the suggestion of the tool makers, I'd go with the first method, so you don't forget that you might get burnt latter.
It seems that you used old "std_lib_facilities.h" header (stroustrup.com/Programming/std_lib_facilities.h).
New version of this header, working flawless for the "hello,world"-program in MSVS 2015, is available at
stroustrup.com/Programming/PPP2code/std_lib_facilities.h
Found it out when had had the same problem studying PPP.

How does #include <bits/stdc++.h> work in C++? [duplicate]

This question already has answers here:
Why should I not #include <bits/stdc++.h>?
(9 answers)
Closed 4 years ago.
I have read from a codeforces blog that if we add #include <bits/stdc++.h> in a C++ program then there is no need to include any other header files. How does #include <bits/stdc++.h> work and is it ok to use it instead of including individual header files?
It is basically a header file that also includes every standard library and STL include file. The only purpose I can see for it would be for testing and education.
Se e.g. GCC 4.8.0 /bits/stdc++.h source.
Using it would include a lot of unnecessary stuff and increases compilation time.
Edit: As Neil says, it's an implementation for precompiled headers. If you set it up for precompilation correctly it could, in fact, speed up compilation time depending on your project. (https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html)
I would, however, suggest that you take time to learn about each of the sl/stl headers and include them separately instead, and not use "super headers" except for precompilation purposes.
#include <bits/stdc++.h> is an implementation file for a precompiled header.
From a software engineering perspective, it is a good idea to minimize the include. If you use <bits/stdc++.h> it actually includes a lot of files, which your program may not need, thus increase both compile-time and program size unnecessarily. [edit: as pointed out by #Swordfish in the comments that the output program size remains unaffected. But still, it's good practice to include only the libraries you actually need, unless it's some competitive competition ]
But in contests, using this file is a good idea, when you want to reduce the time wasted in doing chores; especially when your rank is time-sensitive.
It works in most online judges, programming contest environments, including ACM-ICPC (Sub-Regionals, Regionals, and World Finals) and many online judges.
The disadvantages of it are that it:
increases the compilation time.
uses an internal non-standard header file of the GNU C++ library, and so will not compile in MSVC, XCode, and many other compilers
That header file is not part of the C++ standard, is therefore non-portable, and should be avoided.
Moreover, even if there were some catch-all header in the standard, you would want to avoid it in lieu of specific headers, since the compiler has to actually read in and parse every included header (including recursively included headers) every single time that translation unit is compiled.
Unfortunately that approach is not portable C++ (so far).
All standard names are in namespace std and moreover you cannot know which names are NOT defined by including and header (in other words it's perfectly legal for an implementation to declare the name std::string directly or indirectly when using #include <vector>).
Despite this however you are required by the language to know and tell the compiler which standard header includes which part of the standard library. This is a source of portability bugs because if you forget for example #include <map> but use std::map it's possible that the program compiles anyway silently and without warnings on a specific version of a specific compiler, and you may get errors only later when porting to another compiler or version.
In my opinion there are no valid technical excuses that explain why this is necessary for the general user: the compiler binary could have all standard namespace built in and this could actually increase the performance even more than precompiled headers (e.g. using perfect hashing for lookups, removing standard headers parsing or loading/demarshalling and so on).
The use of standard headers simplifies the life of who builds compilers or standard libraries and that's all. It's not something to help users.
However this is the way the language is defined and you need to know which header defines which names so plan for some extra neurons to be burnt in pointless configurations to remember that (or try to find and IDE that automatically adds the standard headers you use and removes the ones you don't... a reasonable alternative).

Using C++ classes like function that may be defined in several different locations

Between C++0x, C++03 TR1 and boost some things like function and bind can be defined in 3 different places depending on the compiler, eg for VC pre VC9 feature pack you have the boost versions, then you get them in but in the std::tr1:: namespace, and VC10 moves that to just the std:: namespace.
Currently my existing code uses the older boost versions in the boost:: namespace exclusivly, however since for many of my applications and libaries all the boost stuff I used is now in tr1 and C++0x, id like if possible remove the boost dependency from those, while retaining backwards compatibility with older compiler versions.
However I'm not sure on how to make my code locate, include and then be able to access the correct versions :( One thing I have considered is using macros like _MSC_VER to see if the compiler includes the classes I want, (falling back to tr1 and then to boost as needed) and then use the "using somenamespace::someclass;" stuff to move the classes in question into the std:: namespace.
The problem is it seems that in some cases this might break stuff, and I'm not even sure how to tell if VC9 has its feature pack or SP1 installed or not :( I'm also not sure on a tidy way to do it, perhaps provide my own functional.hpp that does the required "magic"?
The main thing is I want to start writing my code for the new standards, but in a way that it will still work with minimal effort on older compilers.
Boost.TR1 already does this for you – it has compiler/version detection logic to use your compiler's TR1 implementation if it's available for your platform, or use the various relevant Boost libraries to emulate TR1 if not:
This library does not itself implement the TR1 components, rather it's a thin wrapper that will include your standard library's TR1 implementation (if it has one), otherwise it will include the Boost Library equivalents, and import them into namespace std::tr1.
From your post it seems like you are primarily concerned about VC++. If thats the case, then I think using preprocessor defines based on the _MSC_VER is probably the most straight forward solution. As you hinted at, just find out what versions were first to provide the various features and include the appropriate header.
As far as how to access them in your code, I would just use several typedefs that are set to different types depending on the included header. If the boost, tr1, and C++0x versions of the libraries provide the same (or similar enough) interfaces, this should "just work". Although, if the type is a class template, plain typedefs won't work, and you'll have to resort to a #define.
Sometimes straight forward is good. It may not be worth making it too complicated. (If you want to support more than just VC++, you will probably have to get complicated.)
Perhaps something like this (as a first thought):
#ifdef _MSC_VER
#if _MSV_VER >= VERSION_WITH_CXX0X
#include <function>
#define FUNCTION_NAMESPACE std
#elif _MSV_VER >= VERSION_WITH_TR1
#include <tr1/function>
#define FUNCTION_NAMESPACE std::tr1
#else
#include <boost/function.hpp>
#define FUNCTION_NAMESPACE boost
#else
#error The current compiler is not supported.
#endif
void func();
FUNCTION_NAMESPACE::function<void ()> funcobj(func);
Although I don't like using a #define to get the namespace, I can't think of another way off the top of my head. I bet there is one, though.
Since you're already using Boost, consider using the macros that Boost.Config provides to test for potentially supported features. Specifically, take a look at the BOOST_HAS_TR1_* macros and the BOOST_NO_* macros.
Note that you have to check for individual features, since not all implementations of TR1 and C++0x support all features of those specs.

What are the practical differences between C compilers on Windows?

A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa. For example when trying to reuse code, which uses windows.h, written for a particular compiler with another, what are the differences to be aware of?
Is there any information about how to produce code which is compatible with either one compiler or another e.g. with either GC/C++ or MSVC/C++? What problems will attempting to do this cause?
What about other compilers, such as LCC and Digital Mars?
The first thing to do when trying to compile code written for MSVC to other compilers is to compile it with Microsoft-extensions switched off. (Use the /Za flag, I think). That will smoke out lots of things which GCC and other compilers will complain about.
The next step is to make sure that Windows-specific APIs (MFC, Win32, etc.) are isolated in Windows-specific files, effectively partioning your code into "generic" and "windows-specific" modules.
Remember the argument that if you want your web page to work on different browsers, then you should write standards-compliant HTML?
Same goes for compilers.
At the language level, if your code compiles without warnings on GCC with -std=c89 (or -std=c++98 for C++), -pedantic -Wall, plus -Wextra if you're feeling brave, and as long as you haven't used any of the more blatant GNU extensions permitted by -pedantic (which are hard to do accidentally) then it has a good chance of working on most C89 compilers. C++ is a bit less certain, as you're potentially relying on how complete the target compiler's support is for the standard.
Writing correct C89 is somewhat restrictive (no // comments, declarations must precede statements in a block, no inline keyword, no stdint.h and hence no 64bit types, etc), but it's not too bad once you get used to it. If all you care about is GCC and MSVC, you can switch on some language features you know MSVC has. Otherwise you can write little "language abstraction" headers of your own. For instance, one which defines "inline" as "inline" on GCC and MSVC/C++, but "__inline" for MSVC/C. Or a MSVC stdint.h is easy enough to find or write.
I've written portable code successfully in the past - I was working mostly on one platform for a particular product, using GCC. I also wrote code that was for use on all platforms, including Windows XP and Mobile. I never compiled it for those platforms prior to running a "test build" on the build server, and I very rarely had any problems. I think I might have written bad code that triggered the 64bit compatibility warning once or twice.
The Windows programmers going the other way caused the occasional problem, mostly because their compiler was less pedantic than ours, so we saw warnings they didn't, rather than things that GCC didn't support at all. But fixing the warnings meant that when the code was later used on systems with more primitive compilers, it still worked.
At the library level, it's much more difficult. If you #include and use Windows APIs via windows.h, then obviously it's not going to work on linux, and the same if you use KDE with GCC and then try to compile with MSVC.
Strictly speaking that's a platform issue, not a compiler issue, but it amounts to the same thing. If you want to write portable code, you need an OS abstraction API, like POSIX (or a subset thereof) that all your targets support, and you need to be thinking "portable" when you write it in the first place. Taking code which makes heavy use of windows-specific APIs, and trying to get it to work on GCC/linux, is basically a complete rewrite AFIAK. You might be better off with WINE than trying to re-compile it.
You're mixing up "compilers" and "OSs". <windows.h> is not something that MSVC C compiler brings to the table: it's C-specific embodiment of Windows API. You can get it independently from Visual Studio. Any other C compiler on Windows is likely to provide it. On the Linux side, for example, you have <unistd.h>, <pthereads.h> and others. They are not an essential part of GCC, and any other compiler that compiles for Linux would provide them.
So you need to answer two different questions: how can I code C in such a way that any compiler accepts it? And how do I hide my dependencies on OS?
As you can tell from the diverse answers, this topic is fairly involved. Bearing that in mind here are some of the issues I faced when recently porting some code to target three platforms (msvc 8/Windows, gcc 4.2/Linux, gcc 3.4/embedded ARM9 processor). It was originally only compiling under Visual Studio 2005.
a) Much code that's written on the Windows platforms uses types defined in windows.h. I've had to create a "windows_types.h" file with the following in it:
#ifndef _WIN32
typedef short INT16;
typedef unsigned short UINT16;
typedef int INT32;
typedef unsigned int UINT32;
typedef unsigned char UCHAR;
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef void * HANDLE;
typedef long LONG;
#endif
Ugly, but much easier than modifying the code that, previously, was only targeting Windows.
b) The typename keyword was not required in templated code to declare types. MSVC is lax in this regard (though I assume certain compiler switches would have generated a warning). Had to add it in a number of places.
c) Simple, but time-consuming: Windows is not case sensitive and many #included files were specified with incorrect case causing problems under Linux.
d) There was a fair chunk of code using the Windows API for many things. An example was for CRITICAL_SECTIONS and INTERLOCKED_INCREMENT. We used the boost libraries as much as possible to replace these issues but reworking code is time-consuming.
e) A lot of the code relied on headers being included in precompiled headers. We had issues with using pch on gcc3.4 so we had to ensure that all .h/cpp files correctly included all their dependencies (as they should have in the first place).
f) VS 2005 has two nasty bugs. auto_ptr's can be assigned to anything and temporary variables are allowed to be passed to reference parameters. Both fail to compile (thankfully!) under gcc but rework is required.
g) Bizarrely, we had template code that was trying to explicitly specialise class template functions. Not allowed. Again gcc refused, VS 2005 let it go. Easy enough to rework into regular overloads once the problem is understood.
h) Under VS 2005 std::exception is allowed to be constructed with a string. Not allowed under gcc or the standard. Rework your code to prefer to use one of the derived exception classes.
Hopefully that's the kind of information you were looking for!
Well this is a quite difficult question. Fact is that MSVC does not support the newest
C standard, about it's c++ compliance I can tell you anyything. Howerver "windows" C is understand by both MSVC and gcc you just can not hope for the other way. E.g if you use ANSI C99 features then you might have a hard time "porting" from gcc to MSVC.
But as long as you try the way MSVC-> gcc you chances will be better. The only point you have to be aware of is the libraries. Most of the libraries on Windows are supposed to work with MSVC and so you need some extra tools to make them accessible to gcc also.
LCC is a quite older system,which AFAIKT does not support much from ANSI C99, it also needs tools from MSVC to work properly. LCC is "just " a compiler.
lcc-win32 is a C Development system striving to be ANSI C99 compliant. It comes along with linker, IDE etc.
I can not tell about the state of Digital Mars implementation
Then there is also Pelles-C which is a fully fledged IDE also.
And we have hanging around OpenWatcom. Which once was quite a decent system but I can't tell how conformant it is.
All in all the "best" you can hope for the easier way from MSVC -> other system but it will probably be much worse the other way round.
Regards
Friedrich
vs2008 is a lot more standards compliant than 2005.
I have had more problems going the other way, especially the 'feature' of gcc that lets you allocate an array with a variable size at run time "int array[variable]" which is just pure evil.
A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa.
This is true if you either (1) use some sort of extension available in one compiler but not another (the C++ standard, for instance requires the typename and template keywords in a few places but many compilers -- including Visual C++ don't enforce this; gcc used to not enforce this either, but changed in 3.4) or (2) use some standard compliant behavior implemented on one compiler but not another (right now the poster boy for this is exported templates, but only one or two compilers support this, and Visual C++ and gcc are not in that group).
For example when trying to reuse code, which uses windows.h, written for a particular compiler with another,
I've never seen a problem doing this. I have seen a problem using Microsoft's windows.h in gcc. But when I use gcc's windows.h in gcc and Microsoft's windows.h in Visual C++ I have access to all of the documented functions. That's the definitions of "implemented windows.h" after all.
what are the differences to be aware of?
The main one I've seen is people not knowing about the dependent template/typename thing mentioned above. I find it funny that a number of people think gcc is not smart enough to do what Visual C++ does, when in reality gcc had the feature first and then decided to remove it in the name of standards compliance.
In the near future you will run into problems using C++0x features. But both gcc and Visual C++ have implemented the easier things in that standard.