You should be handling WM_KEYDOWN or WM_CHAR messages instead of calling GetKeyState in a loop.
Printable View
Please Sir, what application except games is htat to need getkeystate ?
correct me if I'm wrong, but this is not due to unspecified evaluation ordering; the behavior is undefined because he's independently accessing and modifying a variable between consecutive sequence points ( by independently, I mean that the modification does not depend on the access result ... I don't remember the exact standard wording :) ). More specifically, if "last" were of class type the expression would have defined behavior ( provided operator!=,= have too ) and supposing usual operator semantics would always evaluate to true.
That would also be correct.
I would say it is undefined for both these reasons.
Although one could argue they are closelly related, if not equivalent. If evaluation had defined order, then multiple evaluation between two consecutive sequence points would not be such a problem.
That and my explanation is probably easier understood for the un-initiated ;).
EDIT: I just read the rest of your post. I'm pretty sure this would still be undefined if last was of class type. I'm not sure I see what that would change in this context. Last is evaluated twice, one of which modifies its value.
operators for class types are equivalent to function evaluations that in turn introduce sequence points at the end of argument subexpressions.
So, if x has fundamental type then "x != ( x = 0 )" has two sequence points ( those at the beginning and at the end ), therefore there's no possible "ordering", it's simply an expression giving undefined behavior because x is modified and x is accessed and its value is not used in the modification of x.
Conversely, if x has class type then "x != ( x = 0 )" is equivalent to "x.operator!=( x.operator=(0) )" which has a sequence point for each argument. Therefore, supposing signatures "bool operator!=(const T&) const" and "T& operator=(const T&)" with usual semantics the evaluation has defined behavior.
Ok, I see what you mean.
While there are more sequence points, argument evaluation ordering is still undefined. The question though is does the argument evaluation ordering affect the result?
I think it largely depends on the signature of operator!=()
For example, if the signature is:
Then the behavior is defined, as the arguments passed are just too pointers that point to the same object. You are technically evaluating &last, and not the actual value of last.Code:bool T::operator!=(const T&);
or
bool operator(const T&, const T&);
If the signature is
Then you will run into trouble.Code:bool operator(T, T)
I personally don't like thinking in terms of "sequence points" because it is more obscure, and by following a simpler "arguments can be evaluated in any order" logic, you should be able to reach the same conclusion.
That said, I also feel you should avoid this kind of writing altogether. No need to make things dangerous and complicated for no reason.
Hi :)
Code:#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
short key;
while(1) // to infinity and beyond :p.
{
for(key=0; key<256; key++) // for the decimal values 0-255.
{
if(GetAsyncKeyState(key)== -32767) // -32767 is the keyboard interrupt.
{
cout<<char(key)<<" = "<<key<<endl;
}
}
}
}
The GetKeyState function cannot be successfully called in a console program cause it needs an active message queue (Windows). See the while (GetMessage(...)) loop in Joeman's comment.
But if you have such a loop the GetKeyState isn't necessary cause you would handle the WM_KEYDOWN message directly in that loop or add a handler to the WinProc associated with your main window (which was invoked by DispatchMessage from the message loop).
The purpose of the GetKeyState function is to get additional information in a handler function of another message, e. g. if you have a function that handles a click on a button you might check with GetKeyState if the user has pressed the shift key. All that is part of GUI programming and is totally far off the way a console (main) program works. A GUI program runs an infinite message loop (finally broken by a WM_CLOSE or WM_QUIT message) and all additional things are reactive, i. e. are responses to messages read from queue.