New C++ experimental feature: The tadpole operators
blogs.msdn.com
blogs.msdn.com
1. ~ and - are separate operators. - negates, ~ does this: http://stackoverflow.com/a/7207406
2. Integers on computers are typically represented in two's complement notation: http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
3. Now that we know how all the parts work, we can put them together step by step:
~-0010 => ~1110 => 0001
-~0010 => -1101 => 0011 FOR ENTERTAINMENT PURPOSES ONLYhttp://www.amazon.com/Hackers-Delight-2nd-Henry-Warren/dp/03...
There's also HAKMEM[1] and the FXT book[2].
[1]: http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html [2]: http://www.jjj.de/fxt/
I'm grateful that Raymond Chen seems to have a lot of patience for it, because The Old New Thing is a unique gem and would be irreplaceable if shut down, so I'm glad he keeps at it. May his patience stay strong.
e.g.
That problem will go away once the optimizer is
taught to recognize this operator. Then we could
call it the rocket-powered tadpole.
- Raymond
Consider the people, who haven't commented, instead simply skimming this post, without reading deeper, then showing up to work on Monday, and dutifully explaining to colleagues about a new operator they learned of.A couple of years ago he was much more cynical about it, mentioning giving up all together IIRC. Maybe he had a spiritual epiphany about the nature of idiocy on the internet or something, nowadays he seems to enjoy stringing the clueless-and-unwilling-to-learn along a bit.
But yeah, the things he puts up with...
x + ~x = -1
because x has a 1 where ~x has a 0 and vice versa and because all ones 11...111 in two's complement always represents -1 [ * ].Transformation of the last formula yields
x + 1 = -~x
The other "tadpole" operator can be derived from the above one by setting x = -y -y + 1 = -~-y
y - 1 = ~-y
[ * ] This follows from the fact that the sum of all powers of two from 0th to (n-1)th is equal to 2^n - 1. Now, if the sign of the most significant bit in all-ones binary number 11..111 is flipped then the sum becomes -1. 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
}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.
!ErrorHasOccured() ??!??! HandleError();
[1] http://stackoverflow.com/questions/7825055/what-does-the-c-o... That problem will go away once the optimizer is taught to recognize this operator. Then we could call it the rocket-powered tadpole. -Raymond
It seems GCC (4.9.2) already recognizes the operator and generates optimal instructions. int x = 10;
while (x --> 0) printf("%d\n", x);
prints 9 ... 0. The operator is pronounced as "as x goes to 0"Drop this into your address bar: javascript:var%20x=100;alert("x="+x+"\nx-1="+(~-x)+"\nx+1="+(-~x));
Raymond should've saved it for the next April Fools' Day.
Consider the last time you used a machine with big endian, non-8-bit-bytes, and something other than 2's complement integer representation...
At the time of the C standard, architectures were far more diverse; for better or worse, most of the more esoteric ones seem to have died off, leaving us with the ones that do happen to share many characteristics with a VAX.
However, all of those still use 2's-complement integers. According to Wikipedia a few existing mainframes use 1's complement (CDC 3000/6000, UNIVAC 1100/2200).
I know the standard allows different bit representations, but practically speaking, today you're almost never going to find anything other than 2's complement integers and IEEE floating-point; and if you do happen to be working on one of those rare and unusual machines that don't, I think it'd be the least of your worries... even Linus says he doesn't care about Linux running on non-two's-complement or odd byte-size machines.
Tilde and minus look just alike and make reading the code much harder if used together. "Look there's a --i oh no, it's actually -~i or is it ~-i or ~~i?"
Amusingly at least in gcc
#\\ this appears legal
My impression is that this is a parody of something ridiculous he found.