This meant that when accessing data through these handles, you had to write code like this:
(*handle)->field;
or (**handle).field;
Eventually, someone coined a pseudo-operator for reaching fields from a handle without requiring parentheses: handle[0]->field;
[0]-> was named the "sproing" operator (on the theory that it indicates the desired value popping out of a box).This is incorrect.
In Windows, the HANDLE is a typedef for a void pointer, but its usage is usually 100% analogous to a file descriptor - i.e. it is a token passed to kernel space, where the kernel looks it up in a per-process table of open files. I say "usually" because some components have re-used the HANDLE typedef for things which are not kernel objects - for example the HANDLE that comes from FindFirstFile() is actually a pointer to a structure in user-space [which AFAIK itself has a HANDLE to the directory].
I've argued for using uuids for handles from here on out. They are endless; no effort to coordinate handle spaces is ever needed; they work locally and on the network; on some architectures they are even a register width scalar.
int x = 3;
while(x --> 0) {
std::cout<<x<<"\n";
} int x = 3;
while(n <-- x) {
cout << x << endl;
}
which is different because it doesn't include the lower bound `n`. And of course, if typing the ">" is too taxing, the "---" operator is equivalent to the "-->" operator: int x = 3;
while(x --- n) {
cout << x << endl;
}
A few more goodies in this style at http://steike.com/code/useless/evil-c/ (home of the zip-quine.) #define ever (;;)
for ever {
// do something
} !ErrorHasOccured() ??!??! HandleError();
[1] http://stackoverflow.com/questions/7825055/what-does-the-c-o...