LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case (::WM_CLOSE): // <- error C2589: 'constant' : illegal token on right side of '::'
::DestroyWindow(hwnd);
break;
case (WM_DESTROY): // This is perfect
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd, msg, wparam, lparam);
};
return 0;
};
As you see above, in the window callback procedure, I have to change (::WM_CLOSE) to (WM_CLOSE) in order to pass the compiler.
My question is, why does the "::" fails in the case statement?
P.S. the reason I prefer using "::" is that visual studio gives me a list of global functions/macros/etc to choose from so that I don't need to remember exactly what I am looking for. There're so many stuff in windows programming that I find it impossible to remember everything.
In addition, using "::" before global functions/macros/etc seems to work everywhere else other than the case statement. Why is that? Anything special about the case statement?
Thanks, and I'm looking forward to hearing from you.
WM_CLOSE is a macro, which has the value 0x0010. This means that the preprocessor replaces all instances of WM_CLOSE with 0x0010 before the compiler runs. Therefore, by the time the compiler reaches what you typed as ::WM_CLOSE, it finds ::0x0010.
Hence the error message
'constant' : illegal token on right side of '::'
as the constant '0x0010' is not allowed after '::'.
EDIT: More generally, I think it is correct to say that scope does not apply to preprocessor macros.
Don't worry - it's alright to ask for help. If you did want to work this kind of thing out for yourself, look closely at the error. The compiler's messages are (sometimes!) quite informative.
'constant' : illegal token on right side of '::'
It is telling you there is a constant on the right of the '::', so think about why the thing on the right of '::' might be a constant :p
PS: I just noticed this in your OP:
using "::" before global functions/macros/etc seems to work everywhere else
In answer to that, it is probably coincidental. If you write ::WM_CREATE, it will fail because that macro resolves to a constant. If you write ::MessageBox it will work because although it is a macro, it resolves to a function and not a constant.
If you write ::WM_CREATE, it will fail because that macro resolves to a constant. If you write ::MessageBox it will work because although it is a macro, it resolves to a function and not a constant.
Exactly!
My statement
using "::" before global functions/macros/etc seems to work everywhere else
is hence a typical example of imperfect induction, which led to over-generalization.
Thanks for the supplementary advice. I really appreciate it :D