- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Goodness me. I think some bits of my brain just fell out of my ears.
Admin
But...It Works???
Fist!
Admin
Ahhh, C++ template abuse! Template metaprogramming is a classic sign of too much caffeine and intelligence.
Overall, I'm astonished by the exceptionally low quality of these submissions (low quality == good). I have no idea how you're going to judge them....
Admin
Ahhh, C++ template abuse! Template metaprogramming is a classic sign of too much caffeine and intelligence.
Overall, I'm astonished by the exceptionally low quality of these submissions (low quality == good). I have no idea how you're going to judge them....
Admin
I have to say the garbage collection on this is absolute pure unadulterated genius
Admin
I would hope that "357 becomes ((3 * 10) + 5) * 10) + 7" would be "357 becomes ((3 * (2 * 5)) + 5) * (2 * 5)) + 7".
Because, you know, that makes it easier to... something.
Admin
How is this a WTF? It's just another ostentatiously clever nerdy programming exercise. Like the OCR one.
Admin
You can't just say that and nothing more! What is this bug? :-)
Admin
Shouldn't that expression be in some sort of prefix notation? Just because?
Admin
I think this is the best one yet.
Admin
But what was the bug???
Admin
I love the GreedyGarbageCollector which (a) has to be run manually, (b) deletes any subclass of Object that you haven't marked as non-garbage by calling hey_thats_not_garbage, and (c) provides no way of marking an Object as garbage once you've called hey_thats_not_garbage on it.
Admin
This guy can not program C++; he doesn't even know the basics.
is way too complex. It could and should just be
Remember: cycles are expensive.
Admin
I love this entry because of the factor tree, but let's face it: C++ template abuse is just too simple. Combining it with memory operator overloading, any grandma with a C++ tutorial can write the biggest WTF in history if put to it.
P.S.: what we are all wanting to know now is: what's the bug in the windows calculator?
Admin
I love it. There may be two more of these yet to go, but I have a winner!
Admin
OK so you guys are never going to believe this but... I discovered it, and forgot to write down how to reproduce it. Now I can't remember it. I considered not mentioning it because of this, but then I decided it would be more fun to flummox everyone by mentioning its existence but not what it is. Kind of like Fermat's last theorem (paraphrased): "I've discovered a proof to this vexing famous problem of mathematics, but the margin of this paper isn't big enough to hold the solution."
I can tell you the general nature of the bug, though. It has to do with making the calc.exe program confuse itself when dealing with its accumulator versus its memory. The basic idea is that you have a memory, and an accumulator, and when you do your operation, the operation is performed on the two, and the result is stored in memory. Because the calculator supports many forms of operation, such as "+=" or "n + n + n" series of operations, it gets really confusing at some points whether we should use the memory, or the accumulator, for the next operation, or combine them. This is why I implemeted a state machine for my calculator, to keep track of all this. There is a series of operations you can perform on the Windows calculator, by combining the different types of operations (repeated additions, repeated equals presses, +=, then changing your mind about which operation you want) which tricks Windows Calc into making the wrong choice (between memory or accumulator) as to which value to use in the next operation. The next answer it gives, while justifiable as a reasonable way to interpret the keypresses, is different from the way the calculator would have acted without the build up to it. Since my calculator builds up the equations as a tree of numbers and operations in memory, and doesn't try to collapse them to a number until it needs to be displayed, it isn't susceptible to getting confused by prematurely calculating an answer.
Admin
A Z80 does not have 265k of RAM. Among other things, a Z80 is just a chipset which was used in the early 8-bit "microcomputers", such as the ZX Spectrum and derivatives, which had 48k of memory (32k RAM + 16k ROM).
Admin
Subject is computer. Think back to your sentence diagrams in 6th grade.
Admin
Admin
No. A Z80 is an 8-bit microprocessor (not a "chipset" any more than an Intel Pentium is a "chipset"). It doesn't have any memory at all, actually, except for the registers. It has an 8-bit data bus and 16-bit address bus. The original post was stating that the submitter had a Z80-based machine (of which there were many) that had 256K of RAM. You know, like I'd say my current system is an AMD Athlon (2 GB RAM).
He's a pinball (captcha) wizard...
Admin
Ooh, another gem of a comment from Operators.cpp:
Admin
Bad code monkey, it's more of a WTF to say there's a bug and not explain it!! Stop ruining the natural mystique you acquired.
Admin
Hmm. I have a feeling calc.exe is going to get more unit testing in the next couple of days than in the entire lifecycle of windows development.
Captcha: pirates <insert obligatory "Arrrr">
Admin
Did you do any testing that involved the number 95? I foresee some problems there.
Admin
Why? Because "nineteen" is spelled as "ninteen"? That's consistent throughout.
Admin
I love the use of a vector instead of a list for this. Especially when telling the garbage collector that an object really is important.
Although i have to say that the biggest WTFerys of all here are:
know_thyself() - completely unneeded if 'better designed' (== less of a wtf)
allocation of an object to represent current state, for use as a template parameter to do name-based base class function resolution - again with 'better design' (still == less wtf) and some clever typdef-ing this can be completely avoided.
Overall, a nice example. More clever than WTF, but i think this (and most of the other examples) just goes to show that you can't force the genius of slow, natural decay.
Admin
Oh, no kidding. That was a horrible way to band-aid over a problem I could have avoided. I kept getting bitten by the "slicing problem" because I was trying to store derived-class instances into vector slots only big enough for base class sized objects. The extra bits of the derived class just get sliced off - yes it's as painful as it sounds. So I thought, ah the heck with it, I'll just make the sliced base instances able to keep a pointer to the real original object. Sufficiently screwy for a WTF contest, why not? Later I realized I could have stopped the madness by using vectors of pointers, instead of vectors of actual objects. I decided to leave it in "just in case", since I suspect the operator overload functions could've been slicing my objects too.
(BTW, you noticed I use vector<> a lot. It's because I don't fully trust list<> with my data. All that mucking about with pointers to "heads" and "tails" under the covers; gives me the creeps.)
Admin
He's cheating his own spec:
...when it actually comes to the calculations, he defaults to those boring traditional number classes.
Naughty, naughty.
Admin
I imagine that a GCD or LCM function if added to this calculator would be rather um... special.
Admin
My eyes... my eyes....
Admin
Well I don't know if it's a bug, but a few
Number + # + # + # (Loop until calc.exe issues 100% CPU)
Seems it likes to kill the gui, when waiting for the answer, not a seperate thread.
Microsoft ftw!
captcha: CRAAZY ( i know, isn't it)
Admin
Wow. I was sure there's nothing C++ templates can't do, but this extends the borders of conceivable.
Admin
Are C++ templates turing complete? Maybe we can do some calculations at compile time :)
Admin
Yes, they are. Apparently a demonstrator program was once posted to an C++ standard committee list, and there were a few 'OMG what have we done' replies.
http://ubiety.uwaterloo.ca/~tveldhui/papers/2003/turing.pdf
Admin
There is code floating around that calculates the Fibonacci sequence as compiler error messages through C++ templates.
Of course modern compilers die after the first few errors, but you can still see it.
Yes, templates are turing complete.
Admin
Congratulations! You have entirely missed the point of this contest!
Admin
Admin
Yes, I've seen that code. It's... ahem, interesting...
That's at least one thing about C++; it lets you do whatever the hell you want. That's generally a good thing but it also means if you want to brutally commit suicide with it, you're allowed to...
Admin
Also known as:
"C lets you shoot yourself in the foot, but C++ lets you reuse the bullet"
Admin
This calc is intelligent!
If i press "2+2=0" (equealing any calculation to 0) it recognises there's a problem and excuses for the inconvenience! There's also an obscure text of sending to Microsoft my license...
Admin
I hay have found the Windows bug!
Enter the characters 3 + 3 + 3 + = and the result is 18. I never would have thought to do + = except for the comment (which I asume was actually supposed to mean just hitting the equals sign again.)
It is completely reproduceable, and I think it might actually be done to specs. + = adds the number to itself, and - = subtracts it to itself.
The real WTF is that if you do 5 + 5, then hit the + sign again, then realize you didn't want to add another number and hit =, something I can see happening to many people, you get 20. This could just be an example of bad specs.
captcha: pirates.
Admin
IV: You have not found a bug. This is how calculators WORK.
Enter number Enter operation Enter new number, or press = to use currently displayed number.
You'll be hard-pressed to find a calculator (outside this competition anyway) that doesn't do this.
Admin
So are C macros--there was an IOCCC winner once that did a primes test or something like that, entirely in cpp.
Admin
Actually real calculator implementations vary widely in behavior. Today most cheap calculators are built using one of a small number of chips--the only difference between them being the display and key size and shape, and whether the power source is a battery or a solar cell. A decade or two ago...there was more variety.
I remember years ago, when I carried around a briefcase + one or more calculators with me instead of a laptop case + laptop, and when there were actually a lot of calculator vendors and there was a lot of competition between them, being annoyed because there was no standardization for various behaviors between calculators, sometimes even between calculators made from the same vendor.
It was an exciting time. It was the era when calculator vendors competed based on the number of supported functions, but stopped short of actually being programmable ("Our calculator has 2560 functions if you multiply the number of actual mathematical operators by the number of possible states of the SHIFT, CONTROL, and MODE keys and the number of display precision options! The wussy Sharp calculator only has 2359 features!!! And ours has an address book built in with space for 32 names, addresses, and phone numbers, each one no more than 27 bytes long! Buy our 1337 (a1(u1a40r, |7 r0xX0r5!!!!!!!!!!!!!!").
Some calculators simply blink at you if you press = multiple times or without entering a number: 3 + 5 = = = gives 3, 3, 5, 8, 8, 8. 3 + 5 + = gives 3, 3, 5, 8, Err0r. These were boring calculators that sometimes also required you to press C or CE before you could start a new calculation, instead of implicitly clearing the result when you enter a number after pressing =. With this genus of calculator, you'd never have a wrong result if one of the keys started firing multiple times when you press them, a common mechanical problem that plagues all pocket calculators to some degree.
Others repeat the last {operator, operand} tuple: 3 + 5 = = = gives 3, 3, 5, 8, 13, 18. This is quite useful if you need a series of values at some interval, or if you are multiplying instead of adding you can get a series of exponential growth calculations, like compound interest. It's a bit annoying when dust gets under the = key and you keep having to double check every result: when 3 + 5 = 18, it's time to get a new "=" key.
Some use various special key combinations or sequences, e.g. if you wanted numbers at regular intervals, you could get the series 3, 3, 5, 8, 8, 13, 18 from the key sequence 3 + 5 = + = =. That solves the dusty key problem and allows series calculations, but I had to read the instruction manual to discover the existence of that key sequence. Intuitively I would expect the results 3, 3, 5, 8, 8, 16, {16 or 24} from that sequence.
Another variant: 3 + 5 + + + gives the sequence 3, 3, 5, 8, 13, 18.
Accountants and point-of-sale people had (have?) their own special kinds of calculator. Some required you to enter "3 + 5 + =" to get 8 as the final result. Others have special "+=" keys which allow you to chain together several additions (but not other operations). These don't allow sequences like "3 * 5 * 7 =" at all, you'd need to enter "3 * 5 = * 7 =", or even "3 * 5 = 15 * 7 =" (i.e. you can't use a result as an operand).
A bit off topic, but there are RPN calculators, where 3 + 5 = = = results in the sequence 3 STACK-ERROR 5 STACK-ERROR STACK-ERROR STACK-ERROR.
Back on topic, some calculators I've used give you an error if you don't enter a number when expected: 3 + 5 + = gives 3, 3, 5, 5, Err0r.
I owned one calculator where it was possible to put the "=" key into at least two configurable modes. One mode repeats the last {operator, operand} pair, the other doesn't. Ho hum.
Another would repeat the last operator with the current result as operand: 3 + 5 = = = gives 3, 3, 5, 8, 16, 32. I don't know what this could possibly be useful for--I've only seen it on one calculator. I suspect this calculator was built using some kind of hand-optimized gate array, because it only gave correct results for basic calculator functions and went into invalid states at the drop of a hat, e.g. if you pressed the 4 and 9 keys simultaneously it had to be power-cycled before it would work again. That calculator also drew something like 15 mA of power at 9V, so it could (and probably did, since that calculator died an early death) damage its own circuitry if you left it too long in an invalid state.
In general it's not safe to make assumptions about the behavior of a calculator once you depart from a strict "clear number operator number equals" sequence.
Admin
Indeed, that should have been:
Admin
Why not
You know you need a new state, and this way you don't have to see if it's allocated since you will have had at least one defined already at that point.
I'm optimizing out the need for any safety decisions at all, but remembering to delete stuff! Can't have memory leaks =-)
Admin
Anybody understand the prime factorization of this line?
class NinetySix : public Factors<Two, Two, Factors<Two, Two, Seven> >, public After<NinetyFive> {};
Admin
I love the Guns N'Roses reference :) Reminds me of my youthful youth.