Slashdot Mirror


How to Keep Your Code From Destroying You

An anonymous reader writes "IBM DeveloperWorks has a few quick tips on how to write maintainable code that won't leech your most valuable resource — time. These six tips on how to write maintainable code are guaranteed to save you time and frustration: one minute spent writing comments can save you an hour of anguish. Bad code gets written all the time. But it doesn't have to be that way. Its time to ask yourself if its time for you to convert to the clean code religion."

20 of 486 comments (clear)

  1. That was just terrible... by FortKnox · · Score: 5, Insightful

    That has to be the worst written article on cleaning up your code I've ever read.
    This looks like it was written for (and BY) freshmen CS majors.

    Comment your code smartly? No shit?
    Use #defines everywhere? Honestly, I find that having a config file (or DB table) is a lot better, as I can change global variables without even a recompile...

    I'm not saying its BAD advice, its just advice that anyone in the real world already knows.
    How about something new?
    1.) Use test driven development
    2.) Write complete unit tests, including bad input
    3.) If any piece of code is complex enough to require a comment, make it its own function and comment the function. I believe the only thing that REQUIRES comments are classes and methods. Not pieces of code...

    I code go on, but I'm not a writer...
    And neither is the author of that pile of trash...

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
    1. Re:That was just terrible... by AuMatar · · Score: 5, Insightful

      Not every program uses a db. In fact the majority of programs don't. And unless a constant is going to change frequently, or needs to be configured per client, putting it in a configuration file or db table is a bad idea. It makes it fairly likely it will be changed by accident. The only things that should be in configuration files are things you actually expect the user to configure per install.

      As for your advice

      1)Thinking about testing early- good. Writing unit tests-good. The test driven development mentality (write tests instead of design, write unit tests before coding)- bad. It leads to a lot of wasted time, completely rewritten test suites, and throw away work. Thinking about testing early is useful, it may cause you to think about corner cases. But writing them first causes 2 problems- you end up writing the code to solve the tests (rather than solving the problem) and/or you end up throwing away half the test suite in the middle when you refactor the design.

      3)Disagree. The purpose of comments is to make sure that maintainers know what the code is trying to do. Anything block of code thats more than 5 or 6 lines deserves a comment. Breaking all of those into independent functions leaves you with hundreds of 5 or 6 line functions, which is even harder to understand how they interact. Frequently the correct thing to do is not break it into a function and just write a 1 line comment.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    2. Re:That was just terrible... by hobo+sapiens · · Score: 3, Insightful

      "In a real project, you have to scope your constants otherwise you'll have a billion of them in "everything.h" and every time you touch it, the world will rebuild. So nix the "centrally located" file theory."

      Agreed, but some of the things in this article can be applied conceptually if not literally. Don't want a 2MB config file or header file? Right, me either. But break your program down into smaller pieces and declare stuff at that level and group it together at that level. Conceptually the same as what he is recommending, just done according to your actual implementation.

      I too thought the article was very basic, but that doesn't mean that the principles don't apply well to systems larger than a simple game.

      --
      blah blah blah
    3. Re:That was just terrible... by Nyh · · Score: 4, Insightful

      If any piece of code is complex enough to require a comment, make it its own function and comment the function.

      That is just hiding your complexety. A massive tree of functions called each one time is as complex as all the code sequencally in one function. Plowing through the massive tree of functions will cost you more time as reading sequentially through your code whit comments at the places you would have created a function.

      Nyh

    4. Re:That was just terrible... by Lord+Ender · · Score: 4, Insightful

      I disagree. Since I started writing the "main" part of my programs as nothing but flow control (if, else, while) and function calls (which did the actual processing), I find that it is much easier to analyze problems in my software.

      --
      A slashdotter who didn't build his own computer is like a Jedi who didn't build his own lightsaber.
  2. Use a language that checks I/O errors by default by mkcmkc · · Score: 4, Insightful
    It's amazing how much simpler life is if your language will check errors (esp I/O errors) by default. That is, if you do a write and if fails (e.g., because the disk is full), an exception gets thrown, and even if you haven't written any error handling code at all, you get a nice explanatory error message.

    C, C++, and Perl are not "safe" in this sense. Python is. Not sure about other common languages.

    --
    "Not an actor, but he plays one on TV."
  3. Mostly agreed by ZorbaTHut · · Score: 5, Insightful

    I thought I'd make two comments on things that I think he got a bit wrong.

    Tip 2: Don't use #define. Avoid it as best as you can. Use const int. That's what it's for. It will be typechecked by the compiler, it's much harder to produce bizarre errors, and 99% of the time it's better.

    const int NUM_ALIENS_TO_KILL_TO_END_WAVE = 20;

    Tip 4: Warning messages don't work. Don't bother with them. Use assert() - if it triggers, your program will crash with a useful error message. Now that's an incentive to make things work!

    In my current project, out of 25,000 lines of code, I have almost 1100 asserts. And the first number counts whitespace. Any bugs I have get found and squashed pretty much instantly.

    --
    Breaking Into the Industry - A development log about starting a game studio.
    1. Re:Mostly agreed by drawfour · · Score: 3, Insightful

      Not only that, but when debugging, since there is an entry in the symbols for that variable name, you can see what the value is inside the debugger without having to look to find where the macro was defined.

  4. I thought #defines were deprecated in C++ by dpbsmith · · Score: 4, Insightful

    Not that I don't use them a lot myself, but I thought that in C++ you were supposed to try to avoid the use of macros altogether, and in particular were supposed to use consts for, well, defining constants.

    I.e. not

    #define PIXEL_WIDTH_OF_PLAY_AREA 800
    #define PIXEL_HEIGHT_OF_PLAY_AREA 600

    but

    const int PIXEL_WIDTH_OF_PLAY_AREA=800;
    const int PIXEL_HEIGHT_OF_PLAY_AREA=600;

  5. It was fine... by Erasmus · · Score: 5, Insightful

    People who are just starting their careers as programmers are allowed to read articles too. Just because something is aimed at a population less experienced than you doesn't mean that it's crap!

    I'm not sure if it really called for a Slashdot entry, but I've been on a few projects with new coders where a quick read of something like this on their parts would have saved everyone a lot of grief.

  6. Re:Use a language that checks I/O errors by defaul by LiquidCoooled · · Score: 3, Insightful

    Relying on the environment to do all cleanup leads to bad code.
    Every time you create something, destroy it afterwards.
    Assume every action will fail and handle it appropriately.

    I have seen 'developers' assume everything will be taken care of, then when the software gets into the users system their usage patterns make it explode.

    Simple management needn't make a development time longer or harder and allows you to migrate things to other applications/systems with ease.

    --
    liqbase :: faster than paper
  7. Obvious and Wrong in One by 19thNervousBreakdown · · Score: 4, Insightful

    ... if your C code requires you to know the difference between i++ and ++i, it is too complicated.

    Advice on good comments--great--but really, it's just obvious. Anyone that doesn't get how to comment well doesn't want to comment well. And the above quote made me want to wring his neck. If you don't know the difference between those two operators, you should stick to VB.

    --
    <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  8. Felt I should point out by loqi · · Score: 5, Insightful

    ... if your C code requires you to know the difference between i++ and ++i, it is too complicated

    It's not a matter of knowing the difference, it's a matter of the code depending on the difference. If you need to increment beforehand, do it on the previous line. Afterward, do it on the next line. Expressions are like sex: they're better without side-effects.

    --
    If other reasons we do lack, we swear no one will die when we attack
  9. Some more redundancy, care of Brian Kernighan by Kalzus · · Score: 4, Insightful

    "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." - Brian W. Kernighan

    --
    "The Devil does not know a lot because He's the Devil, He knows a lot because he's old." -- unknown
  10. Re:Who wrote that article? by seaturnip · · Score: 3, Insightful

    Somewhere along the course of reading the article, I also got the impression that he wasn't a professional developer himself (at least, a smart one).

  11. Re:Who wrote that article? by itlurksbeneath · · Score: 3, Insightful

    Well, there are a lot of "programmers" that I work with that don't actually have degrees in computer science. Heck, some of them don't have degrees at all and certainly haven't attended "Intro to Programming". I forwarded the article around to several folks here as a "hint, hint".

    --
    Have you ever considered piracy? You'd make a wonderful Dread Pirate Roberts.
  12. Hungarian Notation by PhoenixRising · · Score: 3, Insightful

    For example, there is something called Hungarian Notation. There are lots of flavors of this, but the basic idea is that you put a tag at the beginning of a variable name saying what type it is.

    I wish he'd included a link to the Wikipedia article on Hungarian notation and specifically referenced "Apps Hungarian". Hungarian notation is essentially a cheap way to create programmer-enforced "types". When these are truly new types ("dirty string", "null-terminated string", etc.) not known to the compiler/interpreter, it might be reasonable; this is "Apps Hungarian". However, prefixing an unsigned int with "ul" (i.e., "Systems Hungarian") is silly; your compiler should warn you/error out if you're trying to do something inappropriate with it, since it knows what an unsigned int is. Hungarian notation will be a useful thing until it's as easy to define new types in common programming languages as it is in, say, Haskell, but it should be used judiciously.

  13. Re:Use a language that checks I/O errors by defaul by mkcmkc · · Score: 3, Insightful

    Assume every action will fail and handle it appropriately.

    True enough, but this misses my point. The question is: What happens when a programmer fails to properly handle errors?

    This happens all the time, either because the programmer is not sufficiently competent, or simply misses a check, or because the program in question is a prototype that got pushed into production without being reworked.

    Having the language produce useful error messages by default does not preclude an other strategy regarding error handling, resource deallocation, etc. It wouldn't necessarily even need to be done via exceptions. It just needs to change the default strategy from fail-silently to fail-safe, which is what you really want if you care at all about reliability and correctness.

    --
    "Not an actor, but he plays one on TV."
  14. Re:Who wrote that article? by Anonymous+Brave+Guy · · Score: 4, Insightful

    That's a bit harsh. Apart from writing comments that are a maintenance liability, using C++ macros when constants would be better, mentioning the use of Hungarian notation that is a liability without mentioning the use that can actually be useful, advocating silent failure in the case of failed preconditions, misquoting Knuth and, to add insult to injury, citing a Wikipedia article in support when that article is currently tagged as having dubious citations (I know; I put the tag there a few weeks ago), failing to understand that games development is one of the few areas where early optimisation is basically a fact of life for some genres, and arguing that you shouldn't rely on programmers knowing basic language facilities like the pre- and post-increment operators in the C family, what was wrong with it? :-)

    I am, of course, being facetious. As the author himself points out at the end, much of this stuff isn't obvious to newbies, and it's better if someone tells them earlier rather than later, so kudos to him for taking the time to write it up. I do wish people volunteering such material would get some peer review if they can, though, because the only thing worse for inquisitive newbies than no information is bad information.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  15. Re:Comments are a code smell. by Coryoth · · Score: 3, Insightful

    Refactoring code to make things as clear and obvious as possible is, of course, a good idea. But it is no substitute for actually stating your intentions in the form of comments or contracts. A maintainer coming to search for a bug in code that is clear but uncommented can only discern what the code actually does as opposed to what it was intended to do. Thus if the bug is a result of a gap between intended functionality and what got implemented (as happens often enough to matter) it makes things a lot harder to track down. If you an state clearly and simply what a block of code is intended to do, do it -- it gives a maintainerr something to verify against.