Slashdot is powered by your submissions, so send in your scoop

 



Forgot your password?
typodupeerror
×
Programming Entertainment Games IT Technology

Dirty Coding Tricks To Make a Deadline 683

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?
This discussion has been archived. No new comments can be posted.

Dirty Coding Tricks To Make a Deadline

Comments Filter:
  • by buswolley ( 591500 ) on Wednesday August 26, 2009 @02:51AM (#29197479) Journal
    VBA
  • by Anonymous Coward on Wednesday August 26, 2009 @03:01AM (#29197561)

    The Gamasutra article is dated August 20, 2009. I doubt any Slashdot contributor submitted a link to a 2009 story back in 2000.

  • Wrong question (Score:5, Insightful)

    by julesh ( 229690 ) on Wednesday August 26, 2009 @03:07AM (#29197601)

    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?

  • by shish ( 588640 ) on Wednesday August 26, 2009 @03:11AM (#29197627) Homepage
    This is one of those stories where the story isn't the point, it's the comments that are worth reading, so it's only a problem if we have the same comments :-P
  • Re:One word.. (Score:1, Insightful)

    by Anonymous Coward on Wednesday August 26, 2009 @03:17AM (#29197677)

    It's not irrational. Very often goto is solution to a problem you shouldn't have.

    That, of course, does not invalidate your last comment...

  • Re:One word.. (Score:2, Insightful)

    by EvanED ( 569694 ) <{evaned} {at} {gmail.com}> on Wednesday August 26, 2009 @03:18AM (#29197691)

    Error handling in C code is my typical example of that. It mostly avoids the need for lots of if statements to make sure that you clean up all that you need to and nothing more.

    There are other ways to go about it, but in general I'm not convinced they are better.

  • Re:One word.. (Score:3, Insightful)

    by fractoid ( 1076465 ) on Wednesday August 26, 2009 @03:49AM (#29197849) Homepage
    Every control structure in C++ is equivalent to either a goto or jnz plus some syntactic sugar.
  • by 93 Escort Wagon ( 326346 ) on Wednesday August 26, 2009 @03:49AM (#29197853)

    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.

    Yes, because deadlines are always reasonable and never pushed up. And change orders are a myth.

  • Re:One word.. (Score:5, Insightful)

    by Derleth ( 197102 ) <<chbarts> <at> <gmail.com>> on Wednesday August 26, 2009 @04:07AM (#29197983) Homepage

    Breaking out of a deeply-nested loop, as can happen when you’re looking for a specific element in a multidimensional array. The alternative involves adding state variables and complicating the logic terribly.

  • by u.hertlein ( 111825 ) on Wednesday August 26, 2009 @04:09AM (#29198001)

    "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."

    This is so sad. He notices your code is faster and he's not the least bit curious? (I presume he's some kind of CS prof.) Anyway, good for you, but still... :-(

  • Re:One word.. (Score:5, Insightful)

    by Derleth ( 197102 ) <<chbarts> <at> <gmail.com>> on Wednesday August 26, 2009 @04:14AM (#29198035) Homepage

    I’m a goto-user, but this is a bad reason to use them: If you regard language features as ‘just’ syntactic sugar, why aren’t you programming in raw machine code? That is what everything eventually gets turned into anyway.

    You use gotos when the normal control structures are inadequate somehow. It doesn’t matter what the compiler does; source code is for humans.

  • Re:One word.. (Score:3, Insightful)

    by Darinbob ( 1142669 ) on Wednesday August 26, 2009 @04:23AM (#29198103)
    I think a lot of programmers are superstitious. They do what they teachers taught, without ever stopping and thinking about why they were taught that. So you see people instinctively avoid goto's, or forbid them outright when they get edit permission on style guidelines. I've seen some horrible stuff that avoids gotos, complicating code and making it difficult to read. They heard "goto considered harmful" and "you should prefer structured programming" and translated that internally into "thou shalt not use a goto". Some people even avoid "break" or "continue" in C because of similarity to a goto.

    Similarly, the "there shall be only one exit from a function" is often used as a tautology by some. Combine that with a prohibition on gotos (that lets you jump to the cleanup) and things get ugly.

    Granted, you can get rid of a lot of gotos with some simple language additions (such as a "finally" clause or automatic destructors), but if these don't exist the goto works just fine.
  • Re:One word.. (Score:4, Insightful)

    by zwei2stein ( 782480 ) on Wednesday August 26, 2009 @04:37AM (#29198209) Homepage

    Ewww.

    1) decent languages support labeled for/while cycles and apropriate "break label" constructs. It is not so different from using goto but has much better semantic meaning and thus allows neat optimalizations (with, say, paralelization in mind)

    2) if you do this kind of thing, you are MUCH better off separating lookup code to method or function and simply using return statement once you find it without having to break from cycles per se. Cleaner, more structured.

  • Re:yuck (Score:5, Insightful)

    by quintesse ( 654840 ) on Wednesday August 26, 2009 @05:06AM (#29198393)

    Basically ALL the software you use works like this.
    Welcome to the real world, no need to feel bad.

  • Re:One word.. (Score:3, Insightful)

    by digitig ( 1056110 ) on Wednesday August 26, 2009 @05:22AM (#29198473)

    as well as some oddly structured loops for which try/catch logic doesn't get you all the way

    Such loops are almost certainly buggy, almost certainly maintenance nightmares and I'll stick my neck out and say certainly unnecessary. The logic needs redesigning. So they are examples of dirty tricks to get code out of the door, as the GOTO poster suggested.

  • by Big Hairy Ian ( 1155547 ) on Wednesday August 26, 2009 @05:50AM (#29198653)
    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.
  • Re:One word.. (Score:5, Insightful)

    by FourthAge ( 1377519 ) on Wednesday August 26, 2009 @06:05AM (#29198751) Journal

    Hardly pedantic or lunacy. For example, pick one of the drivers from the Linux kernel, e.g. this one [sourceforge.jp]. Look in particular at the "geode_aes_probe" function.

    The structure looks like a pyramid. On one side is the setup phase, on the other side is the cleardown phase. If one of the setup operations fails, then the "goto" jumps to the appropriate cleardown operation and continues from there. If the top of the pyramid is reached, then return #1 (success) is used. Otherwise, return #2 (failure) is used.

    This function could be written in C without using goto. But would it be as easy to read and as easy to maintain? Doubt it. As it is, it's perfectly obvious what you would need to do in order to add a new capability to the driver. Tricks to work around "goto" would only obfuscate the functionality.

  • Customers (Score:3, Insightful)

    by CarpetShark ( 865376 ) on Wednesday August 26, 2009 @06:11AM (#29198781)

    Have you ever needed to insert terrible code to make something work at the last minute?

    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.

  • Re:One word.. (Score:3, Insightful)

    by 91degrees ( 207121 ) on Wednesday August 26, 2009 @06:19AM (#29198813) Journal
    Surely you could do that as a nested if.

    Whether that is better or not is subjective. "Goto considered harmful" has become dogma, but while your example is a very good example of goto used well, most programmers would use it to write spaghetti code. Barring the use of the keyword means that it does only get used by people who know exactly what they're doing.
  • Re:One word.. (Score:5, Insightful)

    by FourthAge ( 1377519 ) on Wednesday August 26, 2009 @06:43AM (#29198931) Journal

    I'd agree with all of that. Like C itself, goto is a powerful tool that is easily misused by beginners, but is still very useful in the right circumstances.

  • by EdgeyEdgey ( 1172665 ) on Wednesday August 26, 2009 @07:42AM (#29199251)

    but it still feels wrong that part of our finance system is handling complex number of dollars, whatever that means.

    They're called Imaginary dollars, and there's a lot of them about at the moment.

  • Re:One word.. (Score:4, Insightful)

    by TheRaven64 ( 641858 ) on Wednesday August 26, 2009 @07:56AM (#29199337) Journal

    Actually most exception handling constructs are even worse than goto, because they can unwind the stack an arbitrary amount. This is because they are taken from languages like Lisp and Smalltalk, which had accurate garbage collection and stack introspection and so could be used safely, and plonked into languages which have neither. In Java they're not too bad because you have to explicitly declare every exception that you can throw and so they become part of the interface, but they are horrendous in something in the C family. There's a nice Raymond Chen article where he writes the same bit of code with and without exceptions, and it's clear where the bug is in the exception-free implementation (error value ignored) but with exceptions it's very difficult to spot and the number of possible code paths grows alarmingly.

    Goto in C is not like goto in BASIC or many languages from the '70s and earlier, which was basically a higher-level wrapper around a jump instruction. In C, a goto statement is only allowed to jump within the current function, so it doesn't break structured programming too badly. Exceptions and longjmp(), do. Longjmp(), as it's traditionally implemented, is the worst because there is no way for any code in intervening stack frames to handle cleanup and so it's almost impossible to use without causing resource leaks of some kind. Non-local exceptions are almost as bad, because they hide multiple return paths. Sometimes it's cleaner to have two or three different return statements in a function, but with exceptions every single function call is a potential return path unless you wrap every single call in a try / catch block.

  • Re:One word.. (Score:5, Insightful)

    by robfoo ( 579920 ) on Wednesday August 26, 2009 @08:24AM (#29199551) Homepage

    I can't figure out if I'm the only sane one or the only crazy one. Especially given the 'pyramid' referred to - I don't see a pyramid unless it's rewritten to use nested ifs.

    To me, nested ifs are much easier to read - they convey the meaning/intent of the code a lot better. As in 'if this function call works, then do this. Otherwise, just clean up and exit'

    How is this so hard to understand?

    geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id) {
            int ret;

            if ((ret = pci_enable_device(dev)))
                    return ret;

            if (!(ret = pci_request_regions(dev, "geode-aes"))) {
                    _iobase = pci_iomap(dev, 0, 0);
                    if (_iobase == NULL) {
                            ret = -ENOMEM;
                    }
                    else {
                            spin_lock_init(&lock); /* Clear any pending activity */
                            iowrite32(AES_INTR_PENDING | AES_INTR_MASK, _iobase + AES_INTR_REG);
                            if (!(ret = crypto_register_alg(&geode_alg))) {
                                    if (!(ret = crypto_register_alg(&geode_ecb_alg))) {
                                            if (!(ret = crypto_register_alg(&geode_cbc_alg))) {
                                                    printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled.\n");
                                                    return 0;
                                            }
                                            crypto_unregister_alg(&geode_ecb_alg);
                                    }
                                    crypto_unregister_alg(&geode_alg);
                            }
                            pci_iounmap(dev, _iobase);
                    }
                    pci_release_regions(dev);
            }
            pci_disable_device(dev);

            printk(KERN_ERR "geode-aes: GEODE AES initialization failed.\n");
            return ret;
    }

  • Re:One word.. (Score:3, Insightful)

    by microTodd ( 240390 ) on Wednesday August 26, 2009 @08:32AM (#29199633) Homepage Journal

    You were very, very lucky, in an awesome way. None of my programming teachers were EVER that savvy.

  • Re:yuck (Score:3, Insightful)

    by TheRaven64 ( 641858 ) on Wednesday August 26, 2009 @08:36AM (#29199677) Journal
    What, you think no hobby programmers have added quick hacks because they've spent two days chasing a bug and still can't find it? No open source projects have ever added quick hacks to make a feature they want to boast about work in time for their code freeze?
  • Re:One word.. (Score:3, Insightful)

    by Derleth ( 197102 ) <<chbarts> <at> <gmail.com>> on Wednesday August 26, 2009 @08:38AM (#29199695) Homepage

    So formatting is worthless, then? And why do we have so many languages, many of them domain-specific? Compilers don’t care about how understandable the metaphors are or how many lines are needed to do a specific thing.

  • Re:char Str[255] (Score:5, Insightful)

    by dkleinsc ( 563838 ) on Wednesday August 26, 2009 @08:39AM (#29199703) Homepage

    I believe another name for that little snippet is "buffer overflow vulnerability".

  • 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.

  • Re:One word.. (Score:3, Insightful)

    by basiles ( 626992 ) <basile@NOSPam.starynkevitch.net> on Wednesday August 26, 2009 @09:17AM (#29200293) Homepage

    Every control structure in C++ is equivalent to either a goto or jnz plus some syntactic sugar.

    This is almost true, but I see one important exception: the exception machinery in C++ (that is the compilation of throw and catch C++ statements) is not exactly a goto (and neither is longjmp in C). And of course, any (method or function) call and return is not exactly a goto neither. Exceptions,calls and returns also change the stack pointer.

    I would also notice that computed goto (i.e. the goto *p; GNU extension [gnu.org] of C) is compiled as an indirect jump.

    A more interesting concept is continuation [wikipedia.org] Regards

  • Re:One word.. (Score:2, Insightful)

    by gid ( 5195 ) on Wednesday August 26, 2009 @09:39AM (#29200651) Homepage

    Heh, I rewrote it the exact same way--before I scrolled down to this comment. Of course the 8 space indents make it a bit wide, but really, who uses an 80 column display anymore?

  • Re:One word.. (Score:4, Insightful)

    by Bakkster ( 1529253 ) <Bakkster@man.gmail@com> on Wednesday August 26, 2009 @09:45AM (#29200753)

    You use gotos when the normal control structures are inadequate somehow.

    This is the heart of the issue: control structures are a well defined, easy to follow, hard to fuck-up subset of the things you can do with goto. If you can do it reasonably with a control structure, you shouldn't use goto, because it makes your code more readable. If you can't, then you should consider if your program should be restructured (which is why goto is dangerous to novice programmers). If not, then you can use a goto.

    Of course, all bets are off when you're scraping for clock cycles with machine code, but that's not necessary most of the time.

  • by Bakkster ( 1529253 ) <Bakkster@man.gmail@com> on Wednesday August 26, 2009 @10:20AM (#29201307)

    I learned long ago that regular math and financial math follow very different rules.

  • by russotto ( 537200 ) on Wednesday August 26, 2009 @10:34AM (#29201527) Journal

    Nope. Deadlines are often unreasonable. Welcome to the real world. But as a good software developer, you should be able to cope with that too, and without last-minute hide-the-problem hacks.

    Wait, you were serious? Does your hair come to points on the side of your head, by any chance?

    If I could cope with unreasonable deadlines without some sort of nasty compromise, I wouldn't be developing software. I'd be turning water into wine, holding back the tide, etc. "Good software developer" doesn't mean "miracle worker". If the time isn't there before the deadline to solve the problem correctly, either the deadline will be missed or the problem will be unsolved or poorly solved. That's close to a tautology; it's implicit in the term "unreasonable".

  • by Jonathan ( 5011 ) on Wednesday August 26, 2009 @10:46AM (#29201733) Homepage

    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 [wikipedia.org] don't learn it,

  • Re:Example (Score:3, Insightful)

    by sxltrex ( 198448 ) on Wednesday August 26, 2009 @10:56AM (#29201925)

    I pity the developer who has to maintain your code after you've moved on.

  • Re:One word.. (Score:2, Insightful)

    by suomynonAyletamitlU ( 1618513 ) on Wednesday August 26, 2009 @11:54AM (#29202979)

    I can understand what you mean (and your code) and that's probably how I would have written it that way too, but I have to say that the goto code is more elegant.

    Indented code is very useful when you are trying to look at logical levels, but at the same time, it makes it difficult to track the forward flow of code, especially when each step of indentation is very small. For example, in that code, you never have lines that stick out--you have the previous if(...) and then the next if(...) right below it, competing for attention, when in fact it may not even be called next if the statement equates to false. In the original code, the conditional and the code to be run are fairly distinct. You can see "This is what happens normally" and then, having that in hand, go back and track where each error goes, and then you say "Aha, they all come back to the same place, it's just that the closer you got to finishing, the more you have to undo."

    It may be personal preference but I have to say, when things line up, they're easier to understand; too many indentations per line of code is distracting.

  • Re:One word.. (Score:3, Insightful)

    by shutdown -p now ( 807394 ) on Wednesday August 26, 2009 @01:38PM (#29204621) Journal

    But why use a loop + break, when your loop isn't really a loop (i.e. it only executes once)? Every time I see this trick, it makes me cringe: it is just a goto in disguise, and its sole reason for existence is that disguise! If the given situation is best handled by goto (and there are many such cases), then don't be shy and just use it.

  • Re:One word.. (Score:3, Insightful)

    by Alpha830RulZ ( 939527 ) on Wednesday August 26, 2009 @02:35PM (#29205593)

    I did years of work in Business Basic, and we managed to generally avoid go-to's even back then. Plenty of gosubs, but we tried to avoid the goto's.

    I have managed to avoid using a single goto since then. It's been 21 years, and at least half a dozen languages. I don't even recall being tempted or wishing I could.

  • Re:One word.. (Score:2, Insightful)

    by skarphace ( 812333 ) on Wednesday August 26, 2009 @03:48PM (#29206891) Homepage

    Almost all of my code, with very few exceptions, is 2 indents or less.

    Man, to me, it feels like you guys are stuck in the past. I'd like to think most of us have moved away from vi and are using a modern IDE, or at least a graphical text editor. Horizontal scroll is not the devil, guys.

  • by Blakey Rat ( 99501 ) on Wednesday August 26, 2009 @04:10PM (#29207259)

    Yeah, but everybody's experienced the SQL query which, when re-written to say the same thing a different way (i.e. replacing a sub-query with a join) runs 10 times faster than before. The trick to get good at SQL is just to remember these cases and avoid them... the fact that the SQL parser/engine can't do this optimization on its own doesn't speak well for SQL's design.

    It also doesn't help that when extensions are made to SQL (like T-SQL), the very first thing they add are procedural looping operators.

    That's not to say the *concept* of SQL is flawed, just that the language itself is, IMO.

  • by tholomyes ( 610627 ) on Wednesday August 26, 2009 @05:07PM (#29208155) Homepage

    Nope. Deadlines are often unreasonable. Welcome to the real world. But as a good software developer, you should be able to cope with that too, and without last-minute hide-the-problem hacks.

    This "real world" of yours sounds a lot like programming in a bubble. Aside from the constraints of working on top of other's libraries, operating systems, or web browsers, software will always have bugs, and they may not always be under your control. You'll have to defer the lower priority bugs to meet your release date, but without sufficient time to address them-- say, a last-minute bug that would require a significant rewrite of a subsystem that you didn't even author-- you can at least try to make the problem less painful in the meantime.

  • Re:One word.. (Score:3, Insightful)

    by julesh ( 229690 ) on Wednesday August 26, 2009 @07:01PM (#29209849)

    Finite State Machines. They really are quite difficult to implement without goto logic


    int state = BEGIN_STATE;
    while (state != EXIT_STATE)
    {
        switch (state)
        { ...
            case SOME_STATE_OR_OTHER: ... do something ...
                state = NEXT_STATE;
                break; ...
        }
    }

    I fail to see the problem. Or there are table driven solutions that are much more amenable to automatic code generation.

  • Re:One word.. (Score:2, Insightful)

    by EvanED ( 569694 ) <{evaned} {at} {gmail.com}> on Wednesday August 26, 2009 @10:50PM (#29211687)

    It forces one to keep nested ifs to a minimum, the bane of testing and reading comprehension.

    My biggest problem with 80-character limits is that if you have reasonably descriptive identifiers, they tend to be a little long, and so it's not all that hard to go beyond 80-characters even if you are only a couple levels deep in code. If you're in a language with function definitions inside of a class like Java or Python, you've already got two levels of indent to your function body before you've even started writing actual code! With 8 character indents, that's 20% of your line width already gone. If you have an if statement in two nested for loops (not at all unreasonable), that's 5 indent levels and half of your line width! If you then make a function call with two parameters, save the return value, and your average variable length is 8 characters, you're at 80 characters; and that's not even that long of a line, even for someone like me who likes to use a lot of explicit temporaries.

    The other thing is I tend to view line breaks as having a pretty high cost, especially if there are a couple related lines in a row. If you are doing similar operations two or three times in a row, it's nice to see the parallel structure, and adding line breaks obscures that quite a bit. (I used to try to line up operators in such cases, but I rarely do that any more. :-))

  • Bravo, robfoo (Score:3, Insightful)

    by XenonOfArcticus ( 53312 ) on Wednesday August 26, 2009 @10:56PM (#29211731) Homepage
    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.

"If I do not want others to quote me, I do not speak." -- Phil Wayne

Working...