Dirty Coding Tricks To Make a Deadline
Gamasutra is running an article with a collection of anecdotes from game developers who had to employ some quick and dirty fixes to get their products to ship on time. Here's a brief excerpt:
"Back at [company X] — I think it was near the end of [the project] — we had an object in one of the levels that needed to be hidden. We didn't want to re-export the level and we did not use checksum names. So right smack in the middle of the engine code we had something like the following. The game shipped with this in: if( level == 10 && object == 56 ) {HideObject();} Maybe a year later, an artist using our engine came to us very frustrated about why an object in their level was not showing up after exporting to what resolved to level 10. I wonder why?"
Have you ever needed to insert terrible code to make something work at the last minute?
Right before I left from Microsoft: int security = *NULL; // eat it!
Most people don't get why the integral of "e to the x" is so funny. Most math majors don't have a sense of humor.
GOTO :-) (or is that two..?)
[Slashdot Comments We Liked]
Slashdot added a fudge th at mad e tex t h a ve ext ra sp ace s. Ho pe no bo dy foun d i t.
Table-ized A.I.
VBA
A Good Troll is better than a Bad Human.
If you have short deadlines, you end up with issues similar to the bugs Ubuntu needs to smooth out every release. If you go with "It'll be finished when it is finished", Your stable releases can become ridiculously out of date between versions. Debian did a good thing by abandoning the open-ended release cycle in favor of the extremely long but predictable two-year deadlines.
In my last job I had to fix a project management application, because, to allow user administrative privileges, it checked the condition: if (user_id == 1 || user_id == 18 || user_id == 23) {...}. It had a whole system for managing privileges, but someone got lazy at this particular point.
This is literally a dupe from 2000. Wow. It'll take me a bit to look it up...
Often wrong but never in doubt.
I am Jack9.
Everyone knows me.
10 Print "No"
20 Goto 10
Once I had an assignment due and at the last minute before being evaluated, realized I had made a huge mistake, even though the code looked OK...
Too much time playing games in class and I was about to fail the course unit if I didn't pass that one test (right at the end of a semester)
So I ran the program, adjusted the output in a word processor, saved it as a file and threw some code hidden in the comments that read the file, outputted it and exited.
Three minutes later my code was evaluated... I was the only one who passed.
Fortunately, no one investigated too carefully at the time why I was the only one who passed, because after trying to fix the code later in my own time, I realized the source data we were all supplied was corrupted.
Inevitably, Later the same lecturer came to the same conclusion when his program didn't work either and cornered me to ask why mine worked (of course he was suspicious). Thinking quickly, I told him my source data was corrupted and that I fixed that first so my program would work. I don't know if he believed me, but he accepted the story.
Fortunately, I got away with it and I got to keep the pass.
Holy Crap -- among those who've been in the industry for more than a couple of years, who hasn't?
The Gamasutra article is dated August 20, 2009. I doubt any Slashdot contributor submitted a link to a 2009 story back in 2000.
The deadline is looming, I can't spend much more time on this. So, I did the unthinkable -- I packed the controller id into the pointer parameter. I marked it as a horrible hack in a 4-line all-caps comment, and checked it in.
Does not sound so horrible, just make sure the 1,2,3,4 pointers never point at anything "free()"able and it'll work fine.
BTW, is that Wolf 360 game out?
Have you ever needed to insert terrible code to make something work at the last minute?
Wouldn't "have you ever shipped a product without needing to insert terrible code to make something work at the last minute?" be a more sensible question?
My boss however *only* does coding tricks. And he puts them in one big 1k line function.
And is proud of it.
Projects referred to include Doom 3 and the new Wolfenstein, which were not released in 2000. If it's a dup from 9 years ago, it was written by psychics.
In the real world there are deadlines, and it's entirely the developer's responsibility to be able to meet those deadlines without using such "dirty coding tricks". Good developers should have tested their code so as to not have serious problems to fix at the last minute, and designed it so as to be able to extend it easily.
And putting such "if" statements is not solving the problem - not even temporarily - but hiding the bug.
Right, nobody said it was easy. That's probably why software development is not for everybody.
When my deadline comes up and I haven't produced I wait for my boss to ask me for the code then I sucker punch him and run away. The trick is to hold down short term contracts and give false references and hire someone to back them up (another dirty trick). That also makes it easier to dodge the cops when your boss presses charges. It's getting harder though with all this talk of test driven development and short incremental releases. Then the trick becomes to write the most meaningless trivial unimportant tests first - but crucially tests that you can make pass quickly so you don't have to do any real work.
(For anyone insane enough not to realise it, this is a joke. Don't try this at home...or at work).
A 3d model export would break regularly screwing up the texture map orientation on certain polygons. The godawful export couldn't be fixed on the deadline, and risk management said best not to touch it cuz EVERYTHING might bust, let alone all the coders being nailed to the wall by the ship date. So I fixed the model files in an ascii editor. All the art builds that had tweaks needed this "touch" Since it was a hockey game, you can imagine how many goalie pads that was. Oh yeah, you couldn't see if the fixes were correct except in the game engine after more pipeline.
Technically not a code fix, but still a valid solution.
I once worked at a Fortune 25 company in Chicago. They had this ENORMOUS mainframe program written in COBOL that ran their order inventory system which accounted for 20% of the companies revenue. All the guys who wrote this grunting pig of a system had either retired or had passed away. In the middle of the code was the following;
*
* We don't know what this does.
* Please leave it alone !
*
SET INSIDE-INDEX TO 1.
*
* We don't know what this does.
* Please leave it alone !
*
If this statement was commented out or removed the system stopped working. No one could find the problem. People had spent years looking for it but the code was such a mess and the documentation was so useless that they just left it alone and made a note that when the order inventory was re-done to make sure they left this "feature" out. I have been told that many old system have similar problems.
Another day closer to redwood heaven
Have you ever wrote a function / procedure with more then one return statement? Or used break or continue in a loop? Then you can use goto as well. From a structure point of view goto, break, continue and return are all unconditional jumps. They are one of a kind. And looking back in retrospect: Since goto need to be paired with a label it's the least evil of the group.
Note that Pascal the archetype of structured programming had goto but it did not have break, continue or return.
Due to the vagaries of setjmp and longjmp (we were writing a thread manager) and the fact that in C, functions can only return one value we got into a situation where threads (by spec) must be allowed to return an integer, AND the thread manager would need to report if the thread died to the calling function as well (also using the same int). Our group batted it around for a while and didn't see any solutions that were threadsafe under all conditions, so we ended up just specifying that threads couldn't return -1. =)
Cost us 5% off the final grade, I think.
Way back we had a project where we had to simulate entire train traffic entering Helsinki train terminal. Someone else had made the simulator and it ran pretty neatly, but unfortunately crashed mysteriously after about four - six hours of simulation time. Our customers were coming the on monday and I spent my sunday trying to figure out how this simulation worked and what crashed it. Finally I caught the problem, which was as simple as some null pointer to a train schedule or something similar which needed to be referenced. I couldn't figure out why it was null in time, so I just added test for null pointer, which skipped said code. Program ran fine and we got our money. Never figured out what was wrong with it. Luckily it was only a simulation.
This was a pretty important assignment back when I was studying computer science. It added to the final mark mark for that particular class. The task was to write a reasonably complex application in Prolog or some functional programming language, I can't remember which it was. I think the goal was to pair males and females based on their preferences, and find the optimal solution. Of course, I screwed up royally, and nothing worked five minutes before I had to demonstrate my solution.
So in the final five minutes, I changed my code so it would avoid the parts which put it into an infinite loop, and instead simply output a random result. My goal was to tell the prof that it had worked a few minutes earlier, and that I didn't know what had gone wrong, and could I please have another week?
So I demonstrated my app, it gave its random output, and I was about to start with my "damn, it used to work properly" spiel when he said (and this is actually true, even though it sounds unbelievable):
"That's great! The result is correct, and your app is also quite a bit quicker than my own implementation of the problem. Congratulations, I think you're the only one so far who managed to get the correct result so far."
I was so taken aback that I probably just stared at him for a few seconds. Then, I stupidly said "So... You want to see my code?" but he was like "No, the result is correct, and your implementation is very fast, so I don't need to see the code. Good job. Send in the next guy."
And so I did.
Example? Right here:
#include <stdio.h>
void *f(void)
{
a:
printf("Here!\n");
return &&a;
}
int main(int ac, char **av)
{
goto *f();
printf("There\n");
return 0;
}
I worked with some finance guy who was convinced that the square root of a negative number -x was -sqrt(x), and wouldn't hear otherwise. I hacked sqrt(x) to return sgn(x)*sqrt(fabs(x)), but he complained that when he squared the answer, he didn't get back a negative number. Luckily our code was C99 so I changed his dollar type to be "double complex", made him use the complex sqrt, and changed his print function to display creal(x) - cimag(x). The guy said things worked great. I was glad to hear that, but it still feels wrong that part of our finance system is handling complex number of dollars, whatever that means.
yuck yuck yuck keep these stories to yourselves, this is distressing me. If I knew software I was using was coding like this I would feel uncomfortable using it, even if it seemed to be working.
After years of programming, I guess everyone had to cut some corners sometimes. It's also not (always) a problem of goofing off, a module you depend on not shipping in time but you being required to keep your deadline can already force you into doing just that: Delivering a hack that 'kinda-sorta' works, or at least the customer won't notice 'til we can ship the patch.
Yes, that happens often. It's dubbed "Bananaware". Delivered green and ripens with the customer.
We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
Swap to FOSS and change it yourself :p
Our culture doesn't get smarter, it just finds new ways of being retarded.
Have you ever needed to insert terrible code to make something work at the last minute?
Jesus, every fucking day. Sole IT/Everything guy here.
Yesterday it was enabling the personal IIS service on an XP desktop to get a demo going of an OCR scanner server for a board member meeting, because the scanner on loan would not talk to samba shares. Today I commented out some PHP code that read's a database for a web page and instead pasted in an excel page the admin girl had done. Next year that data will not update automaticaly. I will wait for the inquiry as to why and fix it then. Tomorrow i will FTP the javascript code snippet to our intranet web page that is IE 5.5+ only because thats our work environment....except for the graphics dept....but there is only 4 of them.
For some people, the odd incident are cute, amusing anecdotes. For me, it is everyday in the trenches.
In post Patriot Act America, the library books scan you.
PHP signed 32 bit integers .. I really can't say much more without crying.
I thought it was just wonky 64-bit support, until I found out their MAXINT was influenced by the machine the code ran on.
I would write code to get around the apparently wonky support ("So you won't accept a 32 bit unsigned hex literal, eh? ok I'll add two of them together and comment why.. great, that passes all the unit tests..), little did I know that these things were being silently cast to 64 bit floats on the affected machines.
It wasn't until an affected machine had to bit-mask numbers larger than ~2.14 billion that we began to notice the problems. It was an edge condition noone really forsaw, so no tests were written until it was too late. It took FOR EV UHHRR to track this sh1t down, given that it worked on 75% of the servers and 50% of the valid inputs!
Our values were all meant to be 32 bit unsigned, so we eventually had to kludge something together that "utilized" the negative bit of PHP's prefered 32 bit signed values.
Now, most of the sh1t works, but you can't sort the values out of the database easily without all the +2.14bil values preceding zero. (the database doesn't have this @#$% int problem..) We're still gritting our teeth waiting for the other shoe to drop.
This is a "kludge" insofar as we need to abandon PHP as a lost cause, and lack the spare man hours for the effort. :(
People willing to trade their freedom of expression for temporary entertainment deserve neither and will lose both.
Some of the worst I have seen:
In critical C code:
if (some condition)
i *= 0;
else
i *= 1;
And I was the actual variable name.
Even worse, on a different project, an Easter egg that told the user their hard drive was about to be erased, and another that popped up about 30 dialog boxes full of banter between Spock and Kirk. Worst of all this code written in VB and was licensed for megabux then we got hold of it for orders of magnitude more megabux (Most of the original coders were hired fresh out of highschool). It ended up being rewritten (thankfully NOT by me) but we had to get the source to work out how it worked in the first place.
I wish I was making this up.
These posts express my own personal views, not those of my employer
That's completely understandable in this case of programming in Prolog.
Prolog is a declarative language.
You declare the rules, and the system figures out a result that matches those rules.
The problem is that this basically doesn't work. So a Prolog programmer has to write the "declarative" rules in a procedural order so that the run-time system doesn't have to try every possible combination to find (or fail to find) a matching result.
The proper ordering of declarations can be quite subtle. With a modestly complex program you can make a seemingly unimportant change in the order of the declarations and have the runtime go from a second to a week.
In this case the professor didn't (couldn't) know how long a Prolog program to solve this problem should take. He just assumed that you had found a more efficient ordering for the declarations. He might even have thought it was luck rather than deep insight that your program was faster than his. But you have to a decent understanding of the limits of Prolog to get a complex program to complete in a reasonable time, so you had to be good before you could get that lucky.
If you couldn't already tell, I have a low opinion of Prolog and declarative languages. They are "parlor tricks". Much like computer 'Life' and neural networks, simple programs can produce unexpected seemingly-sophisticated results. But they don't get better from those initial results. To compute the answers or results you want in a reasonable time, you end up with at least the complexity of writing things in the traditional explicitly procedural method.
The promoters of declarative language typically don't mention that you end up writing rules in an explicitly procedural order if you want the program to work. If you press them on the issue, they then say "well, OK, it's not actually any easier to write, but it's easier to verify that you've correctly specified the desired result." But if you have to carefully shuffle declarations around, and even then some results unpredictably take centuries to compute, pretty much no one cares.
it made a total hash out of what I was trying to do. But he lost the source code, so I couldn't prove that he did it. Of course we couldn't fix it either. It was in code that calculated people's paychecks. He got fired. I quit.
Taking the address of a label is a gnu extension to C. Its not part of the standard language.
If you've found your code has a last minute bug or god forbid a design flaw then all those nice class/flow/structure diagrams go out the window and its quick and dirty hack time. Unfortunately this happens far to often meaning even the most well controlled projects eventually end up with some hairball code that some poor maintenance coder gets to wrestle with 2 years down the line. After all - if the hack works who's going to bother to tidy it up and rewrite it especially if everyone haa another dozen tasks on their todo list.
?php .... nuff' said. :-)
who just aims to get what is functionally absolutely needed finished & tested by the deadline? Bear in mind that most of my deadlines get set by clueless salesmen who even if they consult me generally tend to ignore what I say and tell the client what the client wants to hear.
I haven't implemented a fully finished system by the deadline in years simply because I can't squeeze 3 months work into 1 month.
Build a Man a Fire, and He'll Be Warm for a Day. Set a Man on Fire, and He'll Be Warm for the Rest of His Life.
I work as a web developper, and I had a project based on a cms (joomla). the project had a very little budget and made use of several publicly available extensions that ran unmodified.
The client asked for a last minute change, putting in the top of the page a form submit button that was in the bottom, and my boss told him we would do it, as it seemed trivial.
We looked at the code for this particular extension, and it was the worst code I had ever read. It had no understandable structure, and modifying this particular extension to display the submit button before the other fields.
modifying the css to display the button on top broke several other pages of the site, so I did the only thing that i could to move this button in less than 5 minutes: a little javascript that took the html of the button after the page loaded and put it where the client wanted it to be.
http://catb.org/jargon/html/story-of-mel.html
It was a very rainy day, both outside and inside, my deadline was comming up fast. My collegue asked if I wanted some coffee before I pull an all nighter, I told him to shut his pie hole... he is kinda annoying, but I might have been stressed. My job was to code and maintain the software for a secret amusement park on the island of Isla Nublar. After many arguments with my boss over sallary and what not, I got fed up, he never appreciated what I did for them, debugging and maintaining millions of lines of computer code. How many others can do that, am I right? Because of that, and greed, I made a sweet deal with another company involving some silly embryos, they paid alot up front!! :):) So I quickly hade to insert some dirty code to shut down the security system so I could get the embryos and stop others from accessing the system I had set up. One dirty thing I did was this: if ( user_session_admincommand_count == 3 && !magic_word) { StartPermissonDeniedSequence(); } . I am happy to say, I got away before they discovered what I had done. I ran into some other problems, but it had nothing to do with my code!! And hey, it was unix!!
I suspect that the "velcro sneaks" sticky walls problem survived at last until Havok 4, or it got recreated there, but it never got discovered because professional game developers just make sure that sticky walls never happen.
But what happens when you've got thousands of people building game geometry who aren't professional game developers?
Second Life had some horrible "Sticky Walls" problems after they upgraded to Havok 4. I wonder what Linden Lab did to fix them?
Yes. But mostly it's not to "make it work"; it's because the customer wants something that is entirely against the original design they asked for.
Hilarious read. Especially the last one, where the seasoned coder invites the younger one to his office and shows him the code line where he pre-allocated 2Mb of memory, so that he can remove it when the project is due shipping after memory constraints are check. I would say this kind of practice will do good on any project from text editors to NASA computer controllers. People respond very well to harsh reality, even if this reality is a bit "fake". Cut down on perceived memory and slow down (intentionally) the CPU, and give them a go at programming. After they are done with polishing code enough so that it runs at decent performance, remove the constraints and see it fly! This is especially good practice for Microsoft, with their ever increasing system requirements and not increasing functionality.
I had a project which was built on a really old CMS that was badly written, we had extended it and hacked it to bits so many times it just wasnt funny.
We had an error somewhere in the code, but couldnt for the life of us figure out where, eventually I resorted to this:
My worst shortcut is to use fixed-sized strings with non size limiting functions, as in:
char Str[255];
sprintf(Str, "%s, %s", Lastname, FirstName);
I really wish snprintf was available on my C implementation.
Non-Linux Penguins ?
First year at university, as part of the end of year project, we coded a shortest path algorithm to work out the distance between two stations in the London Underground system. However at 4am a couple of hours before the class presentation we discovered a bug! This was that if you chose the station 'Bank' it could for example take you to 'Embankment' (since it contains 'bank'). Our 'fix'?? We renamed Embankment to... Embonkment! Nobody realised in the presentation! :)
So we had a race condition on database transactions using two-phase commit, your usual mind-fucking WTF situation, drove us up the walls for days, you all know what I mean. We knew it was a race condition because if we put a sleep() statement at the end of one of the transactions, everything ran fine. sleep(10) was always long enough, and since all of this ran asynchronously in the back end, an end user would never notice the difference.
So we went to the customer. We told them that we could continue to bust our brains trying to find a "real" fix, and didn't know how long that would take, or we could just leave the sleep() in. And we could even make the length of the sleep interval configurable, so they could try to make it shorter than 10 seconds, if they really felt like fiddling around with it.
The customer went for the configurable sleep().
Always keep a sapphire in your mind
> Once I had an assignment due and at the last minute before being evaluated, realized I had made a huge mistake, even though the code looked OK...
I once did almost the same thing, except that I wrote the entire assignment the first day we got it, during class. But I couldn't turn it in yet. And nearly forgot about it. So I turned it in at the last minute...
Except that I had misread the specification! Oh, the program worked just fine, but it printed everything to the screen. It was *supposed* to go to output.txt. That would've been trivial to change, if I actually had any time. But now I was out of time and couldn't change the code I had submitted...
With a bit of quick thinking, I actually managed to convince the TA that the problem was that you were supposed to execute the program as:
java MyProg > output.txt
So instead of getting a zero, I got 98%, because I had failed to document this.
Most code gets assembled into GOTOs (jumps) anyway. I'm sure some competent programmers can manage their own GOTOs just like a compiler can.
syntactic sugar is just fine, but what I would really like is syntactic caffeine.
As of Postgres v6.2, time travel is no longer supported.
So it was 1999 and I was working for a mom and pop software shop, we had been acquired by a dot com. All our money and toilet paper stock options were held until we delivered the re-branded product with source. Part of the "rules" said we had to have only C/C++ and VB6 source, NO OTHER LANGUAGE.
....(you get the idea)
. We finished converting a few rogue scripting modules and things like that, which creep in over time. But we COULD NOT find the source code to one of our VB6 DLLs (an old one that had not been changed since it was first compiled in VB6). We searched and searched and eventually the fastest coder(not me) started rewriting it. We were 1 day from delivery date and there was no way he could finish it, so I ran it through a disassembler.
the C++ code we delivered looked like this:
int functionName(int parm) {
_asm {
push esi
mov esi, dword ptr ds:[esp+8]
mov dword ptr ds:[edi], esi
retn
}
It was unreadable, but it compiled and worked and we got our money. I still wonder what they ever did with that... since the software is still in use...
One of my uni courses our assignments required us to build circuits on breadboards in class - no opportunity to work on it otherwise. My lab partner and I were having problems with one assignment which, despite being wired properly, refused to produce the required output. After checking and rechecking wires, swapping out gates, etc., we were finally down to the last five minutes of class with no idea what to do next. Out of frustration, my partner reach out and scrunched the entire mess of wires in his fists and held them there.
"Try it now"
It worked. He just sat there while I dragged the prof over to evaluate it. As soon as he was done, my partner let go and it stopped working again.
A friend and I were writing a program for our semester long college project. It was supposed to be a file manager that worked on both Linux and Windows. The night before our presentation, I found that in Linux wxWidgets had a bug where widgets wouldn't automatically resize when the window did. The quick and dirty fix was to lock the window size when running in Linux and only demonstrate window resizing while running in Windows.
There is an assumption that code is always meant for humans to read.
We had an easter egg in our code that was in a routine scheduled to be executed only at 0-dark-30 when our users were long gone. But someone later called the routine as part of the loading process, and the users ended up seeing it anyway as they signed on at start of day. It made people smile, so we left it in.
A few years later, we were telling a client that we couldn't add their new feature X because we don't have the memory. At that point the director said to get rid of the easter egg and then it'd fit. (A few hundred bytes was not going to make a difference, but our director didn't care, it was a perception thing.) What we got instead was a hundred bug reports that the easter egg wasn't displaying, and that they "needed" to see it so they'd know when start of day was complete.
John
When you're writing code for embedded microprocessors, there is no nice, warm, run-time environment. When your code gets to the end of main() what does it do? It certainly doesn't return to the operating system (what operating system? there is NONE, just the code you write, yourself) with an error or success value. it just carries on, executing whatever random noise was left in the eprom from it's manufacture.
Under these circumstances, having a GOTO is not merely permissable, it's pretty much mandatory to get back to the beginning of your execution again. If you have been so brainwashed that your fingers are physically (apologies to people without fingers, please excuse the insensitivity) incapable of typing those 4 letters you can use other constructs, such as while(1) {... } but the effect is the same and may even create the same code. So don't kid yourself that GOTOs are bad, or even that they don't exist. They are one of the world's most useful, misunderstood and maligned instructions that EVERY processor has.
Learn to love them and make it a personal goal to write at least one GOTO loop a day
politicians are like babies' nappies: they should both be changed regularly and for the same reasons
There is an assumption that code is always meant for humans to read.
Well, some people like trivial literature, others like to read something more demanding. :-)
The Tao of math: The numbers you can count are not the real numbers.
That's the good thing about open source! All of the dirty hacks the devs use eventually get weeded out of the code as time goes on! Honest!
I always just hard-code all my levels - it's easier to just go back and recompile (which takes 15 seconds in C or 0 seconds in python) than code all the extra logic in for reading from files. As another plus, this makes it harder for other people to cheat. Speaking of cheating, once I called my player save file "makefile" to discourage people from looking at it or modifying it.
And, I never split my code into multiple files - scroll and Ctrl+F were good enough for my grandfather, and they're good enough for me!
This is the code for the Apollo 11 lunar lander flight computer.
http://code.google.com/p/virtualagc/source/browse/trunk/Luminary099/LUNAR_LANDING_GUIDANCE_EQUATIONS.s?r=258
and yes some of my code is in there along with the equivalent of a few "goto's
Lots of bright people worked on this and in some circumstances a "goto" is required.
*--- Sometimes a majority only means that all the fools are on the same side. ---*
I use a lot of Ada in my job. There was one control feature that had to be hacked in such that event X in process X needed to terminate a condition in another process. Rather than putting in the traditional communication events through the RTOS with appropriate procedure/function handlers, this is what was done (it needed to be done *NOW*, apparently):
:= message_off;
procedure foo is
type state_type is ( message_on, message_off );
-- This is the same state the message can be in package Y
state : state_type;
pragma import (Ada, state , "packagey_message_x_state");
begin
state
end foo;
The pragma import is like doing an extern in C. Basically this procedure just aliased ton the internal state variable and cleared it. Nasty, nasty code.
We had a project in a class on the Motorola 68K Processor using assembly to build a circuit to represent a particular lighting intersection. We then had to write the code for the timings or for the switches for when new cars arrived. Everything was going well, we had a very elegant piece of code and we tested it in a simulator and it seemed to work fine, but the last week or so when it came time to build everything and demonstrated it, the thing was just not working.
We ended up tearing it down to the drivers for the lights and testing each one individual to verify they were good, and after three weeks of work I narrowed it down to a section of counter code that was not incrementing. I looked at that code for hours, and the lab tech didn't know why it wasn't working either. Then on a whim I grabbed somebody's board with the 68K on it and switched it with ours, and the thing worked. Turned out several of the boards had been fried by some group earlier in the week we were beginning to test it.
Man was I mad, We didn't have the code from before we scrapped it down to simple timers, and even if we did, there wasn't time to build the circuit, so we built it as quickly as we could doing the bare bones and passed. Man were we pissed though.
Have you ever needed to insert terrible code to make something work at the last minute?
Do you mean, have I ever *not* done this? Hmm... hard to say. Probably not.
Paleotechnologist and connoisseur of pretty shiny things.
Back in college, we were at a programming competition and I was the on-the-keyboard coder for one of the problems. We had 10 minutes for the problem and I coded it quickly, having decided on the best algorithm before sitting down. Part of the solution was a sorting routine on a list. We were using Visual C++ although we were all not C++ experts at the time, and so rather than mess with the STL and the possibility of having to read documentation, I did it all from scratch. I knew that sort was already in use by the standard library, so I called my routine mysort.
Apparently, however, Visual C++ includes a mysort in its standard library. So, with the clock ticking down and the solution's only impediment to our victory being an identifier conflict, I renamed the routine the way that any one of us would have: myfuckingsort. We won the competition.
In this particular competition, the judges were not supposed to read our code - they just run the output of your code on the input and check for correct output - so I felt safe when I typed what I did. However, one of them came up to us afterwards and told us that they do in fact usually read the code of the winning team to see if we did anything unique in our solution. Yep. Sure did. And my classmates and professors never did let me live down what was affectionately nicknamed the fucksort algorithm.
But I might have missed some. There is not much difference between "return 0;" and "ret=0; goto exit_function;". Both are unconditional jumps there is no rational reason why one should be "considered harmful" and the other not.
select "nothing to see here move along..." from dual;
A lot of terrible code is a result of management forcing unrealistic deadlines on developers, or refusing to slip a deadline to accommodate some unforeseen problem.
I worked on a large data visualisation application with an unrealistic deadline, which our department was writing for another department, on their budget. In order to prevent it from eating into our budget money, it had to be released by a certain date. It needed several months more than that to be even nearly ready, but when the deadline came the managers announced that it was finished and released on time. Management high-fives all round. Then it immediately announced that the customers couldn't use it yet because there were some minor bugs which had suddenly been discovered (i.e. all the missing features which would make it any use at all).
I also had a boss who would give you something to do, make changes to the design on a daily basis while you were doing it, then before it was anywhere near ready demand that you stop work on it immediately, check the (unfinished, untested, part built) code in and start work on something completely different. He did this to all the developers, and the code was riddled with overlapping #ifdefs around chunks of unfinished code just so the build didn't break. Then of course he announced "Good news, everybody! We're going live in three weeks!" when the cobbled-together mess was at least six months from being usable. Cue more panic-coding just to make things work, and then the deadline came and went because he'd thought up yet more wacky features to add, starting the cycle all over again. Bug database? Change requests? Unit tests? Peer reviews? Documentation? No such luck. Even the features he wanted weren't clearly defined, you just got a two-hour rambling phone call which contained about five minute's worth of useful information (but it didn't matter, because he'd change his mind when you half-done developing it, or forget how he wanted it doing and yell because you doing it how he originally asked).
It's like those sci-fi films where the ship breaks down.
Captain: How long will it take to fix the engines?
Engineer: At least 24 hours, sir.
Captain: You've got 8, now get to it.
Engineer: No sir, really. 24 hours minimum if nothing else goes wrong.
Captain: We take off in 8! You have your orders.
Engineer: But seriously, we can't...
Captain: La-la-la-la I can't hear you!
Cress, cress, lovely lovely cress
I use GOTO regularly while debugging and even in some production-level stuff. I've cultured the good|bad habit of leaving 'on error goto errortrap' in code. Predictable errors are one thing. It's those unpredictable ones I usually need to have the whole thing stop without causing problems. Do not pass go, do not collect $200, and absolutely never, ever 'on error resume next'.
There was some code that another sysadmin wrote long ago at work that was doing something like sifting through a huge file tree, checking the files' attributes and content, then deleting the file if certain criteria had been met. Something happened with one of the checks where instead of bailing out, it just started deleting files... all 2.5 million of them.
Thankfully, we have hourly backups.
Reviewing the problem, the first line of their code was 'on error resume next'. They didn't know why it was there, but that's "just the way we've always done it"... which is obviously a warning flag. I changed it to a GOTO -- explained the whole error trap thing to them in painful detail -- then ran it again. The GOTO and error trap did exactly what was expected so we could fix the problem with the object tests... without risk of destroying live data.
Sure, there are better things than the GOTO out there, but to borrow the analogy from hairyfeet, once in a while, you still need a chainsaw to cut down a tree.
I had a good example of goto in my code recently. It was searching through linear hash table. So you start in the middle of the table, and when you are at the end, you want to restart from the beginning.
So I set up a guard pointer (first at the end of table), then go through the table looking for my element (until I get to the guard pointer), at the end, if the current pointer equals guard pointer (I haven't found the element), I goto to the loop again, but this time the guard is set to the original starting point.
I challenge you to rewrite this without goto and without duplication of the search loop.
Not necessarily: sometimes you need to free memory, resources, etc.
I don't use goto anymore, but back in the days of 16-bit and 12K stack, where we had to malloc() local variables, a 'one return' goto proved useful to branch to free() without excessively nested 'if's.
Slashdot entertains. Windows pays the mortgage.
http://xkcd.com/292/
I think a better question to have asked would be, have you ever NOT had to insert something into code as a deadline approached, that you knew in your heart of hearts was nothing less than the worst possible hack imaginable.
This is going back a bit, to around the late 80's in fact.
We were sat at a copy party trying to finish writing a intro we'd planned to release at the party (a scroller in blitted on fonts using halfbrite shading over a funky moving picture, at the time quite nifty) but we'd saved the bitmap with all the fonts as a 1 layer amiga bitmap, and due to memory restrictions enforced by dpaint they had to be no wider than 400 pixels I think. So I had wrote some routine to process the ascii text we wanted to display, and every nth position from the base position of A, it incremented a Y counter for the blitter source map so say H would be on row two and 30pixels down the bitmap and say +80 in the X so the bit blitter could pick up just that letter image for its source. Only something was very wrong with my logic somewhere and for ages it refused to print certain letters out, instead going slightly mad and printing random garbage instead, and I hadn't had any sleep for two days and was the only coder in our group present . So we wrote the entire scrolltext in what passed for leetspeak in the day, managing to avoid the problem letters completely although it looked a bit insane on the day.
After a good nights sleep, it was a one line fix to sort out (and involved a pointer looping under certain conditions), but of course we'd already released the demo and everyone had gone home...
This is the code for the Apollo 11 lunar lander flight computer.
http://code.google.com/p/virtualagc/source/browse/trunk/Luminary099/LUNAR_LANDING_GUIDANCE_EQUATIONS.s?r=258
and yes some of my code is in there along with the equivalent of a few "goto's
Lots of bright people worked on this and in some circumstances a "goto" is required.
Help me out here, then. You're one of programming's elders, landed guys on the moon, best war stories ever. The epitome of professional code design, the ne plus ultra of deployed applications.
One question, then: why "Tuna Shooter"? Was there ballistic toro involved in Apollo?
if((login.equals("geust")&&password("1234")) || loginOk(login, password)) //someone used the wrong value for pi and all the functions fave been fudged to work... //there was a bug we cant fix... stop reporting the errorr
.
while(fuckupCount 100) {... if(!startApp(app)) fuckupCount++;}
.
.
double pi_ish = 3.1415673;
.
catch(NumericFormatException e) {
}
catch(Exception e) {
logError(e);
}
Actually, C has functions that are supposed to do this and work; setjmp and longjmp are supposed to let you jump between functions etc and unwind the stack; if I recall correctly, I even used them for interrupt handling code in MS DOS.
This is machine code. Gotos and conditional gotos are the only control statements you have!
Goto s can always be eliminated, with a state variable and a __repeated__ test. But at a cost, not a large cost, but extra code and execution both. In fact, the old academic fad against goto was a consequence of the dreadful programs that used to be written in FORTRAN and Cobol, in my view "perform" is far worse.
... surfices.
So more modern languages have specialised goto s, switch, break, try, catch, finally; which are clearer, even though C, C++ confused endcase and break loop from BCPL. Yet some GOTO s remain the clearest way of writing code, I do not like the state-retest one bit more and as for the suggestions that you break an integral piece of logic into 3+ subroutines, I find that crazy. I like the logic, and thus the code to read down the page, to the greatest extent practical, even if you have a 1000 line routine.
I do not like the style of C++ and Java coding where any given bit of logic is spread across 4 files and mandates the use of a code visualizer eg SourceNavigator, or an IDE.
Code should be as simple and as easy to read and understand as possible. Thus puttting things in subroutines should reflect that they are used more than once, and are an execution abstraction.
This is why "ho-hum" rules, and most coding standards and metrics stuff leads to bad code, eg I dont want large block comments, which I can assume were never debugged and are out of date to interrupt the code. If the algorithm is unusual or complex a link, see
Exactly.....
*--- Sometimes a majority only means that all the fools are on the same side. ---*
First, a brief trick from my school days. We had a professor who didn't even look at the source. He'd come by, you'd "run" the app, and he'd look at the output. I'd forgotten about an assignment, so right before class I ran the calculation we were supposed to be "solving" on my calculator, hard-coded a cout in the app to print the answer, and stuck a pause in there to make it look like it is working. One of only three people who passed the assignment.
------------
Now the real one:
This one happened the night before I was supposed to deliver a milestone build. Short development time, lots of work, we've all had 'em.
So I'm working on a function that is taking all of the inputs and generating a list of all combinations. I haven't slept in about 2 days, I'm wired on caffeine. The code I end up with (quickest to write) looks like this:
*Note, these are just placeholder variable names, the real source code used descriptive names, used the values to pull data out of classes, etc*
x = [1,2,3,4,5]
y1 = [8,9,0]
y2 = ['a', 'b', 'c']
y3 = ['w', 'x', 'y', 'z']
x = [[e, f, g, h] for e in x for f in y1 for g in y2 for h in y3]
Keep in mind that in the actual function, it would have gone up to y11, with all 11 being parsed in that one list comprehension.
It works great, very fast, but it is *completely* unreadable. The code is still there (with about a page worth of comments). That one line convinced me to never consume seven 2-liters of Mountain Dew in a day and try to program. I don't drink soda/tea/coffee very often. Hell, I probably could have written something better DRUNK.
Yes there was. Lots of issues involved if the systems went down. I used to have the protocols in the attic someplace. I'll look up there but i haven't looked at them since i got my divorce I might just weep nostalgic.
Sorry
*--- Sometimes a majority only means that all the fools are on the same side. ---*
I really love this bit :
DMP* VXSC
GAINBRAK,1 # NUMERO MYSTERIOSO
ANGTERM
sbb
It's one partial component you might use to implement Coroutines. or you might use it as a building block for implementing green threads or some other kind of cooperative multitasking. You'd want to wrap it in macros, or better yet, use setjmp or a real programming language like Scala or Erlang... Come to think of it, you asked what this is a good solution for, not a crappy solution... hmm...
# Page 731
# BURN, BABY, BURN -- MASTER IGNITION ROUTINE
BANK 36
SETLOC P40S
BANK
EBANK= WHICH
COUNT* $$/P40
*--- Sometimes a majority only means that all the fools are on the same side. ---*
No. I am never 'at the last minute' and I am more competent than that. You losers just put your feet in it. I hope you all get the sack as you deserve.
Well, in part, but another important lesson in science labs is learning to report the truth, even if is disappointing and not what you want. This is an important lesson and unfortunately even some well known scientists don't learn it,
I once had a program that kept coming up with a really odd numerical error. I ended up tracing it back by printing out various variables along the way so I could make sure that the interim calculations were correct.
However, when I printed out one particular variable, the code suddenly gave the correct result. Removed the other debug prints, and it still worked. However, if I once again removed the line that echoed out the variable-in-question, it would screw up.
I checked all around that statement to make sure there were no termination issues (aka it wasn't the "WRITE VAR1" statement at fault, but a higher-up that wasn't terminated until my debug WRITE) and there was nada. Even my prof had a look and found nothing, but the output was definitely bugged without that line.
We lost a few marks for having a debug line in our final output, but nobody ever was able to figure out why it wouldn't calculate properly without it.
Not that I have done this but I have seen plenty of web desigers use a css 'display:none' or before that was happening put comments tags around data that they did not want the site visitor to see.
In some CAD software getting ready for a show, a programmer entered this late night gem causing significant head banging (into the concrete wall). Something like:
if (object == U2) continue; // U2 disallowed cuz it is my favorite rock group
Of course all of the components on a schematic are traditionally named U1, U2, U3...
This might be the same guy that complained I was playing music on the weekend because he was trying to sleep in his cube, doh!
if (isCustomFont()) {
#ifdef BUILDING_ON_TIGER
RetainPtr fullName(AdoptCF, wkCopyFullFontName(m_font.cgFont()));
#else
RetainPtr fullName(AdoptCF, CGFontCopyFullName(m_font.cgFont()));
#endif
String nameStr(fullName.get());
m_allowFontSmoothing = (nameStr != "Ahem");
}
Working on an application for a now defunct airline. Developers embedded similar to the following Oracle 7.3 SQL in an executable:
select *
from bob A, fred B
where A.key = B.key;
Rule-based optimizer depended on ordering the tables in the from clause correctly for an efficient join (driving table will be last in the list), but the developers got the order wrong. So, I used a hex editor to reverse the aliases A and B in the from clause in the executable. Voila, performance went from dog slow to blisteringly quick without a recompile (no time for that).
for politicians .
HELP!
I'm trying to get this code to work. I'm at an altitude of 6,000 ft, hovering over the Sea of Tranquility, and the darn thing keeps crashing! (The code, not the lunar module.)
PLEASE don't connect me to that Bangalor helpdesk again! I am in serious trouble here!
Has this been tested for Y2K compliance?
Did we not pay our last support bill?
- Major Tom
Have you found it yet?
The cancel button is your friend. Do not hesitate to use it.
I remember 15 years or so back; I was trying to get an application convert a text file into a Word document. I was using all these nice OLE calls from within Delphi but for some reason it didn't work.
The deadline was looming, so I ended writing a function that copied the files and renamed the extension to DOC. When opening it in Word it didn't show any errors. Unfortunately my client found out and went ballistic. By that time I luckily had the word conversion code working and was able to provide a new executable that worked as requested.
"Ballistic toro"? Flying cows? flying bull[shit]? I confess I don't quite understand the phrase.
If you're working in an environment in which variable names and comments matter, then you still write with descriptive variable names and comments, and just pre-process the source to remove comments and shorten variable names. Writing obfuscated code directly is just foolish.
Bah! I want to see the script for the simulation out in the desert/soundstage.
I feel sorry for people that don't drink, because when they get up in the morning, that's as good as they're gonna feel
...until somebody mentioned the Wing Commander hack.
I used to work at an ISP and helped with the custom browser installers burned onto CD-ROMs. During testing we discovered that NT 4 would behave badly if you started using it too soon after the install had completed. No time to figure that one out. It had to ship.
Solution? Throw up a fake progress dialog that said "configuring settings" that ran for about 30 seconds after everything else was done. We were banking on the user not fiddling with his machine while it was still doing the all-important configuring.
For all intensive purposes, "whom" is no longer a word. That begs the question, "who cares"?
What does this mean?
"HERE IS THE PHILOSOPHY OF GUILDENSTERN"
Was that one of the engineers on the project?
I'm a good cook. I'm a fantastic eater. - Steven Brust
Were you also responsible for some of the code used wtih Apollo 13 as well?
Cute, but it wasn't a software failure. In fact the computer was able to do things it was not designed for in order to get them home.
I'm a good cook. I'm a fantastic eater. - Steven Brust
I think this code would be more entertaining if there was a "OMG WTF just happened" with a little ASCII Skull and Cross bones in the comments..
Just saying :-)
We used to ship "Vapor" Code to make revenue during a quarter. Essentially if a product hadn't completed a test cycle by the due date, we'd ship a placeholder application that would happily install but then when first run would go out and get the latest "updates" which would be the software that was supposed to ship. Not a great practice but it was management's directive. Customers usually waited a few weeks to install the software anyway so the testers and the bug fixers could refine the product using that gap time.
At a place I once worked, the policy was to catch any and all possible outcomes to death, however impossible.
So I'd taken a habit of coding in a rather verbose and unique message for each condition that should never occur; one day a call came from a client with an odd error message asking users what the score of a game (between a hockey team and a basketball team) was on a specific season final, which helped us quickly identify the relevant portion of code.
Since the condition was indeed impossible to reach, we were able to return some harsh questions to the dev guy at the client's site, who had meddled with a library without supervision, which turned out to be the root cause of some odd intermittent bugs the client had been suffering of late.
Sometimes it's fun and helpful to be a little creative, though perhaps it's best to stick to clearer error text, since it initially took the client a whole day to eliminate the theory that a virus was causing the error to appear, instead presuming the application was the culprit.
tell it again! tell it again!
My current favorite: Use IKVM to convert a java .jar file into a .dll that will work under .Net and Mono!
No, I will not work for your startup
Needless to say, there was a bit of a panic to review all his "released" code ...
FTA one of the hacks was a workaround for a supposed "two-in-a-row" CRC32 collision! What are the odds, I thought? Thats like, getting struck by lightning at the precise moment as scratching the jackpot winning lottery ticket while.... Then it dawned on me... Apparently they only used filenames to generate the first 32-bits of the ID, and they used file contents to generate the second 32-bits. So all one would have to do to cause a collision would be to copy a file to another directory in the project! On the surface it was a good idea, just ruined by bad implementation. Their "quick" solution was to just add a space to the end of one of the files. A more proper solution might have been to change the implementation to use the entire path+filename to generate the first 32-bits. I wonder why they didn't just do that?
In production systems I do like to occasionally fight for a time off ('cleanup timeout or I quit!') and let someone else to have a stab at the code I feel I have fucked, really, really, fucked, up. And funny enough, when they do account for most/all the edge cases, two or three different input paths as per specifications and variations in states, it might not be the same, it might not be worse, but for sure as hell I am just about in a WTF mode reading their code as I can imagine anyone reading and deleting 'surplus' code blocks from mine are.
In real life code sucks. Just sucks, and it just doesn't involve you (again). Unless you manage to position yourself in nuclear plant or simlar critical systems where your inputs are guaranteed to be x to y and if not - oh well, it's too late anyway.
And as a word of warning - if you see a code that appears to be equal to 'if (1 == 1) return 1;)' - well, this is the time to become _extremely_ careful.
(*When I'm not drunk I dream of working in true RT-embeded systems with watchdogs, crystals, documentation describing cycles-per-instruction and no stupid heap sharing...)
Have you ever needed to insert terrible code to make something work at the last minute?
A properly designed project will never require the last-minute insertion of bad code. Rather, proper planning and foresight allows terrible code to be implemented in each and every step of the process.
I've found an excellent practice is to define what problem I want to solve, and who my target audience is. In the first case, the problem I'm trying to solve is often the same: I want to make money. And my target audience is anyone who likes purple primates, which is obviously everyone. Next, since I know I can't please all the people all the time, I throw their expectations out the window and instead create whatever I want.
Also, a little tip for you beginners: Recursion is super fast, so use it for EVERYTHING. In fact, you should only need one function or method in the entire program. If recursion is too intimidating, you can start out by overloading all of your methods to a single identifier. Eventually you can merge them together by adding optional parameters to a base method.. but DON'T be tempted to use case switches. Instead, use nested if statements, like this: if ![condition1] {if ![condition2] {if ![condition3] {[dostuff for condition4]} else {[dostuff for condition3]} else {[dostuff for condition2]} else {[dostuff for condition1]} Also avoid line breaks, the way I did, because they make your program run slower. Obviously 1 line is less than 2 lines, so use this to your advantage.
https://www.eff.org/https-everywhere
That's just because you don'rt eat enough sushi (unless your are just kidding/trolling). :: http://en.wikipedia.org/wiki/List_of_sushi_and_sashimi_ingredients#Finfish
Toro = fatty Bluefin tuna belly
Experience teaches only the teachable. -AH
char * password = "password";
...
scanf("%s",password);
This little lovely gem is likely to get past most levels of testing, and fail miserably, insecurely, in the field. No, I haven't personally done this, but I've long suspected similar code is the reason for those "You can't have more than 8 characters in your password..." limitations on some websites.
Someday I'm going to start a website for absolutely subversive C source code. It will be my personal therapy...
The society for a thought-free internet welcomes you.
Doom 2 Sector Hack:
From p_enemy.c:
==============
if (gamemap == 7)
{
if (mo->type == MT_FATSO)
{
junk.tag = 666;
EV_DoFloor(&junk,lowerFloorToLowest);
return;
}
if (mo->type == MT_BABY)
{
junk.tag = 667;
EV_DoFloor(&junk,raiseToTexture);
return;
}
}
==============
If anyone remembers the "outpost of hell" level of Doom2, this code caused sector 666 (doors to outer area) to drop after all the Manucubi (fat guys with flamethrowers) were killed, freeing all the Arachnotrons (baby spider demons), and raised sector 667 (stair to end of level) after all Arachnotrons were killed.
I used to design levels for Doom2 and I came across this interesting behavior when trying to force doors to open after enemy deaths. I finally realized that only on level 7, and only sectors 666/667 were affected in exactly this way. Sure enough, when I was able to view the Doom2 source, there was the "ugly hack."
-Dan
I once documented a web server written in COBOL.
The entire server is an amalgamation of dirty coding tricks.
My favourites were the...
# TRASHY LITTLE SUBROUTINES /. (too many 'junk' characters in that). Who knew?
(I originally planned to quote more of the code, but apparently a snippet of the Apollo 11 lunar lander flight code isn't "geeky" enough for
(about 3/4 down the page)
That could be the character in Hamlet.
In 1996, I had to finish a game that was coded by another guy (who had quit).
There was a weird bug, when you took a sword and jump on the same place, after 2-3 minutes, the player passed through the floor and kept falling (reappearing at the top of the screen).
My boss wanted to know how much time I would need to fix this bug, but I sincerely told him I didn't know.
He immediately asked to remove the sword from the game.
In the same game, there were 2 more unfinished levels, that had probably required 3 months of graphic work (they were graphically finished).
Since the game had to be released soon, we didn't include these levels (this was 20% of the whole game !).
In another company, a similar fact appeared: we had to release a game and there were some levels to integrate.
The levels were simply ignored.
At a previous job of mine, I was working with the SCons build system; it's basically Make, but written in Python. It's actually really nice if you know Python, but also fairly slow. In it, every filesystem object (files and directories) are maintained as "Nodes" in a big graph.
Anyway, the project was using an old version of SCons along with lots of legacy code, and with this version, for some reason, when my build script was added, a conflict resulted where a Node in the build system representing a file was initialized twice, once as a directory, once as a file (it was actually a file).
Nowhere in my build script was this file even referenced; it wasn't even a dependency of any of the stuff being generated by my code. After hours of trying to find what was causing the conflict, I eventually figured out I could call File("theFile") to (sort of) "cast" the Node as being a File in the build system, and it would work. To this day, I believe that's how it's implemented, and I have no idea why it worked. :)
Although hard-coding things is generally frowned upon, I can see why it is used for "quick and dirty" reasons. What really caused the FAIL in the OP's code is the short-circuit AND (&&). If a single & was used, the artist would have seen their object.
Because "Good developers" will never be thrown into a project that is running over time and budget?
Because "Good developers" will never have to work with poorly designed legacy systems?
Because "Good developers" will never have deadlines moved forward for commercial reasons against all technical advice?
Because "Good developers" don't have to deal with last minute change orders?
Because "Good developers" review all bugs reported for every supporting application they use and even know of bugs in the supporting applications before they are reported?
Because "Good developers" only ever work on projects with other "Good developers" and so never discover bugs in libraries / other code they are calling at the last minute?
Because "Good developers" are never temporarily pulled off projects to work on a system crash type issue and thus have their own projects fall behind?
I could go on and on and on and on...
A "Good developer" could test their code until it is bullet proof and will still have problems if one of the supporting libraries also being developed either changes functionality or is buggy. A "Good developer" has no control over situations where the customer says "I want this change in production by tomorrow and accept the risks associated with the lack of testing".
Many of us dream of this utopian universe where none of those conditions occur and we could all be "Good developers". Until that time I, I am always wary of people claiming to be "Good developers" who never run into these problems as, with very few exceptions, they have never worked on any decently sized commercial app.
Let others smack you down, but with nearly 30 years of programming experience in numerous languages, I'm with you. Indented branching flow seems clean, stable and maintainable. I got dissed for a job i applied for because my code was designed this way instead of the "enlightened" way of throwing exceptions. Exceptions are ok, I guess, if everything is a C++ objects that self-destructs when it goes out of scope, but reality doesn't always work that way. In retrospect, I'm glad I'm not at that job.
-- There is no truth. There is only Perception. To Percieve is to Exist.
GOTO's are like jump instructions in assembler.
Every program made must have a jump instruction.
GOTO's jump to places in the code
those places have different state sets
different local variables
and you had better get the there without any non-maskable interrupts diverting you.
That said - most times a goto is used only to make the code clearer or to escape a failed operation.
Bill Plaguer said that Clarity of Code is a great asset.
So don't use goto's if the surrounding code is likely to change.
Whoah... Respect ! Was that a real CPU (what kind ?) or a microcontroller ?
TRASHY LITTLE SUBROUTINES
SPECIALIZED "PHASCHNG" SUBROUTINE
Isn't that spelled Phishing ?
Non-Linux Penguins ?
You have an ID 10 T error.
Saved me the trouble of having to say it. Thanks.
Towards the end of my projects we had lots of similar hacks. But we have it on a separate BRANCH, IDENTIFY it as a hack so it doesn't get reverse-integrated AND we #define it with the game name around it so it WON'T happen in the other games.
Interesting. Is this some kind of assembly language for an old obscure CPU? I have been coding in assembly language for various architectures but I haven't nothing like that. It's quite different than what I am used to and a lot of keywords/opcodes there seem preety strange.
Also, why bother excuse yourself for the use of goto equivalent opcodes? People argue that got sucks but only for higher level languages. Goto in assembly is like a JMP or something, of course it's necessary and not to be blamed. I used to be annoyed with how people avoided goto in high level language but even bother about it in assembly?
Compilers also use gotos.
"It's too bad that stupidity isn't painful." - Anton LaVey
> If I'd been the TA, I would have given you 98% too despite your misreading of the spec, even without your "fix". Come on, a 0 for getting it 98% right? With a trivial fix?
There are a lot of people who care more about the test than the purpose it's supposed to serve. At work, we have a safety guy who gives us safety tests.
Some of the questions are absurd and do nothing to keep us safer. They could easily be changed to focus on the actual important safety issues we face. But he won't do it. He doesn't want to make the test "easier" even though he's asking people questions that simply aren't relevant to them.
Our last test was on fire extinguishers. There are four classes of fire: A (solid fueled fires), B (liquid fueled fires), C (electrical fires) and D (metal fires, e.g. from burning magnesium).
We have absolutely nothing that could case a class D fire at work. We have no fire extinguishers that can extinguish class D fires ANYWHERE. Half of the test was about class D fires.
We have lots of huge drums of highly flammable liquids (class B fires). There were only two questions about them, and one was "What kind of fire is a class B fire?" There was NO discussion about why you don't pour water on them (because you spread the fire). They did have a question asking what kind of fire water is good for, but it was so indirect it hardly made a point. Because the tests are mainly for the factory workers (but are given to everyone), I don't think that most of them understand why you don't pour water on a gas fire.
But all of them now know more than they ever cared to about metal fires, because that's the way the test was constructed.