Without using your friendly neighborhood compiler, consider this code:
1 2 3 4 5 6 7 8 9 10
#include <iostream>
#include <Windows.h> //Assume you have a correct windows.h header
#include <limits>
int main()
{
SetConsoleTitle("My First Program"); //Assume this expands to SetConsoleTitleA
std::cout << "Hello, World!" << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Do you think this will compile? If not, what do you think causes the error? It should only take you a macrosecond to decide.
I actually spotted two problems. The one you were looking for and the misuse of SetConsoleTitle (should be SetConsoleTitleA). Whether or not that would cause a compiler error would depend on your settings, though.
[...] the misuse of SetConsoleTitle (should be SetConsoleTitleA). Whether or not that would cause a compiler error would depend on your settings, though.
I fixed the first post. With VC++, it's a macro that determines whether to use the A or W version based on whether you're in unicode or not. In this instance assume it's the A version. ;)
Well, that was the only problem I was seeing. If that's not it, then I see nothing wrong with it. Both I and g++ -pedantic (no need to mention the possibility of false positives, thank you) agree that the code is valid.
Windows.h defines max as a macro, which breaks the call to std::numeric_limits::max. This can be avoided by #defining something before windows.h is included... like NO_MIN_MAX or something -- I forget the exact macro.
There's another problem: cout can't output "Hello, World!" that early in the main. It will output unintelligible nonsense instead. You first need to call sip(coffee); for at least 5 iterations.
Yep, it only took Disch a macrosecond to figure out that is was the max macro. Now, the other question: Why doesn't it break <limits>, which is included after <Windows.h> ? This one I don't actually know the answer to, because when I include my own headers after <Windows.h> they break.
I wasn't sure either, but after testing this is what I discovered (VC2010 Express -- not sure if this is standard or not)
max is defined with parenthesis:
#define max(a,b) //...
So it will only substitute instances of max followed by parenthesis... such as this:
1 2 3
max(); // will be substituted -- but will error because there's not enough params
max(1,2); // will be substituted correctly
max; // will not be substituted (no parenthesis)
With that in mind you can do something like this:
1 2 3 4 5 6 7 8 9
#include <iostream>
#include <windows.h>
int max = 5; // no parenethesis, so no macro substitution
int main()
{
std::cout << max; // OK, no macro sub -- prints "5"
}
With that in mind you can avoid the macro substitution when declaring a function by putting the function name inside parenthesis:
1 2 3 4
int (max)() // no macro substitution, legal (but weird) function declaration
{
return 5;
}
This is how limits declares all of these functions.
The proper #include is actually <windows.h>
(That's with a lowercase 'w'.)
Well...in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include in is Windows.h (That's with a uppercase 'W'.)
I know that Windows filenames are not case-sensitive, but that does not mean that someone's build environment isn't...
This is true but does cause a problem. While I make every effort to ensure the included files are case-sensitive you do get situations like this. Traditionally it was windows.h but currently not* so I go with the current one as that is the one that I am programming against.
Why does it matter whether the 'W' in Windows.h is upper or lowercase when Windows only uses case-insensitive file systems by default? You won't be including Windows.h on Linux...