Follow Slashdot blog updates by subscribing to our blog RSS feed

 



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 Jack9 ( 11421 ) on Wednesday August 26, 2009 @02:56AM (#29197517)

    This is literally a dupe from 2000. Wow. It'll take me a bit to look it up...

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

    by wilx ( 1065624 ) on Wednesday August 26, 2009 @03:12AM (#29197633)

    The goto statement is very useful. Your dislike of it is irrational. Do you even know why you do not like it? Often, goto is the best solution to given problem.

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

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

    So, where's your example?

    Finite State Machines. They really are quite difficult to implement without goto logic and is exactly what you do when discussing theory.

  • by krischik ( 781389 ) <krischik&users,sourceforge,net> on Wednesday August 26, 2009 @03:33AM (#29197771) Homepage Journal

    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.

  • by Trahloc ( 842734 ) on Wednesday August 26, 2009 @03:59AM (#29197919) Homepage
    He's fighting in the civil war we're apparently not having, guess he fixed our timeline.
  • Re:Study Assignment (Score:2, Informative)

    by dintech ( 998802 ) on Wednesday August 26, 2009 @04:54AM (#29198309)

    Probably he didn't spend much time implementing his version so wasn't too worried. He probably invests most of his time in actual research instead of pesky undergrads.

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

    by beelsebob ( 529313 ) on Wednesday August 26, 2009 @05:17AM (#29198443)

    Yes it is, goto requires a label, and thus requires someone reading your code to go hunting for it. Return is known to push control flow to the exit of the function. One obfuscates code, the other doesn't.

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

    by Anonymous Coward on Wednesday August 26, 2009 @05:21AM (#29198471)

    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.

    The most common use of "goto" in that circumstance is to enforce "only one return".

    Which is every bit the pedantic lunacy that goto-hate is.

  • Re:Example (Score:5, Informative)

    by 7 digits ( 986730 ) on Wednesday August 26, 2009 @05:31AM (#29198539)

    OMG. I didn't even knew you could write that in C (and I have my name in the comp.lang.c FAQ...)

    Of course, I checked C99, and, no, you can't write that:

    3.6.6 Jump statements

    Syntax

                        jump-statement:
                                        goto identifier ;
                                        continue ;
                                        break ;
                                        return expression<opt> ;

    identifier being defined as:

    identifier:
                                        nondigit
                                        identifier nondigit
                                        identifier digit

    So, goto *f() is a no-no (as is probably &&a)

    But, anyway, wow. Gcc actually compiles that to something that somewhat runs...

  • Re:Example (Score:3, Informative)

    by Anonymous Coward on Wednesday August 26, 2009 @06:38AM (#29198905)

    Yes, it is non-standard. But quite useful for some things (although not in the way written above). Consider a function that needs to return and then resume where it left off the next time it is called. Could be done by wrapping it in a large switch, but this is more direct and efficient.

    #include

    void *f(void *p)
    {
            if(p != 0)
                    goto *p;
            return &

    a: printf("A\n");
            return &

    b: printf("B\n");
            return &

    c: printf("C\n");
            return &
    }

    int main(int ac, char **av)
    {
            void *p = f(0);

            p = f(p);
            p = f(p);
            p = f(p);
            p = f(f(f(f(p))));
            return 0;
    }

    [and perhaps it's time to get myself an account on here... captcha: "untested"]

  • char Str[255] (Score:3, Informative)

    by dargaud ( 518470 ) <slashdot2@@@gdargaud...net> on Wednesday August 26, 2009 @06:47AM (#29198957) Homepage
    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.
  • Re:One word.. (Score:3, Informative)

    by Aladrin ( 926209 ) on Wednesday August 26, 2009 @06:52AM (#29198997)

    I have not used a 'goto' statement in about 15 years now. But it's not some irrational fear. It was all due to someone saying 'there's no situation that requires a goto' and 'goto statements make code hard to read'.

    And after I used goto a little more, I realized they were correct. In any good, modern language, 'goto' is completely unnecessary and makes your code harder to read.

    If you're breaking out of a loop, you should use 'break'. If you're continuing a loop, 'continue'. If you're handling an error, throw an exception. If you're calling another piece of code, make that code a function and call it properly.

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

    by ArsenneLupin ( 766289 ) on Wednesday August 26, 2009 @09:05AM (#29200109)
    That's why God invented the finally clause. Any cleanup that absolutely cannot be skipped goes into finally.
  • Re:One word.. (Score:4, Informative)

    by EvanED ( 569694 ) <evaned@NOspAM.gmail.com> on Wednesday August 26, 2009 @09:21AM (#29200357)

    How is this so hard to understand?

    It's not. But nor is code that uses goto in the idiom that FourthAge posted above.

    My objection to that code is that if you do even just three or four allocations, you start getting very large indentations pretty fast, especially if you like 8-character indentations [sourceforge.jp]. (They get pretty long even with 4, which is what I like!) This causes a problem if you restrict yourself to 80-columns [sourceforge.jp].

    Arguably this is a problem with restricting yourself to 80 columns, but that's not entirely unreasonable even if I'd rather the limit be ~100. But guess how many your code uses? Your longest line is 109, longer even than my longer preference. Even if you use 4-character indentations, your longest line is still 80 characters.

    If you reformat your code to use 8-character indentations and 80-character column limits, your code would become a bit uglier as you'd have to wrap four lines (a couple of which don't really have a good breaking point), and hence a little harder to understand on its face.

    By contrast, the original code fits entirely within 80 characters (admittedly only just) without anything remotely like an awkward line break.

    Further, in some sense it doesn't entirely follow the flow of the code. Perhaps this is a vice and not a virtue, but I tend to think of places where there's an unusual condition (like a failed allocation) as not on the same "level" as normal control flow. In this sense, I would think of that procedure as basically linear "with some provisions for exceptional conditions". In that sense, your proposal of the cascaded ifs doesn't really match my mental model of how the code behaves -- the indentation of the normal code changes depending on how many exceptional conditions might arise, and there's not really any reason why it should by that model. By contrast, the original code matches it.

    (Incidentally, "linear with some provisions for exceptional conditions" is basically how I'd write it either in a language that supports exceptions or a language that has RAII. In the former case, there's a decent chance do just one try block for the body of the function, and in the associated catch test to see if each item is allocated in turn. (This doesn't match the structure of the real code exactly, but it's closer to it than it is to your nested-if code.) In the latter case, you'd have basically the real kernel code except that the deallocation would be in the RAII objects' destructors. Again, no nested ifs.)

  • setjmp, longjmp (Score:1, Informative)

    by Anonymous Coward on Wednesday August 26, 2009 @10:04AM (#29201017)

    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.

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

    by inviolet ( 797804 ) <slashdot&ideasmatter,org> on Wednesday August 26, 2009 @10:16AM (#29201231) Journal

    From the linked article: [joelonsoftware.com]

    People have asked why I don't like programming with exceptions. In both Java and C++, my policy is:

    • Never throw an exception of my own
    • Always catch any possible exception that might be thrown by a library I'm using on the same line as it is thrown and deal with it immediately.

    I have done code that way, before exceptions came into vogue. To do it right, you've got to have many many many error-checking if() statements after every call to any function that could fail. That could maybe be done as neatly as with exception-handling, if one was ever careful to maintain one's error-codes in a single numeric heirarchy, so as to allow 'families' of errors. The error-checking statements can then select for specific errors or for families of errors, like this: if (errorCode & ERROR_FAMILY_FILEIO).

    But that is a lot of work, and the code won't be any cleaner than with exception-handling. In fact it will be uglier because you can no longer just call a bunch of functions in a row without checking returns, allowing a single exception-handler at the bottom to catch any errors it thinks it can handle.

    Nor is the author correct in contending that 'throw' is somehow less visible or less handy or less maintainable than 'return'.

    And he won't get the very very nice exception-handling support that some languages like C# offer.

  • Re:One word.. (Score:1, Informative)

    by Anonymous Coward on Wednesday August 26, 2009 @10:50AM (#29201803)

    This'll add the loop code for something that will never loop, even on an optimizing compiler (How will it know that you'll definitely break out at some point?)

    Besides, cleanup1() will almost certainly have to wait until after action2() in most cases. I'd say increase cleanup_stage for every action performed, then use a switch() {} with no breaks

    case 2: cleanup2();
    case 1: cleanup1();

    but that's just goto with a fancy wrapper.

  • Re:One word.. (Score:1, Informative)

    by Anonymous Coward on Wednesday August 26, 2009 @11:10AM (#29202149)

    1. you quickly will run out of indentation space, unless you use a shallow indentation, which is a readability problem of its own. The goto-variant allows the "meat" of the function to be just a couple indentation levels in.

    2. If you later add another initialization step, you have to re-indent everything. Even if your editor makes this easy, you'll end up with a huge .patch file which will be painful to merge with any other changes to that function

    3. I actually prefer your style for simple cases (2-3 steps) but sometimes when doing kernel work you end up having to do lots of init/cleanup steps and the goto-style starts to become MUCH more readable than deep-indentation. Basically the goto-style scales to any number of init/cleanup steps while the nested variant would be unworkable with >8 steps

  • Re:Prolog Assignment (Score:2, Informative)

    by eison ( 56778 ) <pkteison&hotmail,com> on Wednesday August 26, 2009 @11:17AM (#29202255) Homepage

    You know, SQL is declarative, and definitely one of the most powerful and useful programming languages available today. I suggest refining your opinion to hate languages that try to make entire problems declarative rather than limiting themselves to appropriate pieces, such as data querying.

  • Re:Prolog Assignment (Score:4, Informative)

    by QuoteMstr ( 55051 ) <dan.colascione@gmail.com> on Wednesday August 26, 2009 @11:30AM (#29202467)

    General-purpose declarative languages are bunk, I agree.

    However, domain-specific declarative languages often work pretty well. Consider build systems (Make, ant, etc.), or SQL, both of which are declarative.

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

    by dcollins ( 135727 ) on Wednesday August 26, 2009 @11:40AM (#29202691) Homepage

    "How is this so hard to understand?"

    For me, it's hard to understand because your most highly indented lines wrap off the edge of the window, back to the left margin, wrecking the indentation cues. In an IDE, it sets a limit on how many conbditions you can check before having to scroll around to see the whole function.

    I used to work at a company where this was the standard and I was never fond of it.

  • Re:Prolog Assignment (Score:3, Informative)

    by Abcd1234 ( 188840 ) on Thursday August 27, 2009 @05:10PM (#29223115) Homepage

    If you couldn't already tell, I have a low opinion of Prolog and declarative languages.

    Better not tell your database [wikipedia.org], it might get offended...

  • by Anonymous Coward on Thursday August 27, 2009 @05:43PM (#29223581)
    Actually, no it didn't. You just got lucky. The Ada standard says the compiler is allowed to assume a variable is not aliased unless it is marked aliased or volatile (or atomic, which also makes it volatile). One of my compiler would have worked fine, the other would optimize this away.

Understanding is always the understanding of a smaller problem in relation to a bigger problem. -- P.D. Ouspensky

Working...