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

78 of 486 comments (clear)

  1. Who wrote that article? by Anonymous Coward · · Score: 2, Funny

    Captain Obvious?

    1. Re:Who wrote that article? by KingSkippus · · Score: 5, Informative

      Maybe it was the note at the top of the article that says, "Level: Introductory."

      Maybe it was the author's comment at the end that said, "At this point, you may be thinking, 'Wow. That was a big waste of time. All of this stuff is obvious and everyone knows it. Why did anyone write all of this?' I hope this is what you're thinking. Then you're already smart. Good for you."

      But somewhere along the course of reading the article, I got the impression that he wasn't writing it for professional developers (at least, smart ones), but for people relatively new to programming.

      But then, maybe I'm just stating the obvious, Cap'n...

    2. Re:Who wrote that article? by Enselic · · Score: 4, Interesting

      I wonder what mushrooms he were on when he came up with that coding style... (yes, this is the actual indentation he used):

      Void change_score(short num_points)
      {
          if (num_points < 0)
      {
      // maybe some error message
              return;
      }

          score += num_points;

          if (num_points > 0)
      make_sparkles_on_score();
      }

    3. Re:Who wrote that article? by jjrockman · · Score: 3, Informative

      Not to nitpick, but it's not "by Microsoft". It's published by Microsoft, but written by Steve McConnell of Construx.

      --
      Quit jabbering on the phone while driving. You are not that important.
    4. 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).

    5. 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.
    6. Re:Who wrote that article? by hobo+sapiens · · Score: 2, Interesting

      Agreed, especially considering that this article was not so much about commenting as it was about writing self-documenting code. To leave indentation out of that discussion is to be quite remiss.

      On the other hand, I work with many CS degree holders who could greatly benefit from this article. So while to some it's obvious stuff, just because it's obvious advice doesn't mean that it's always followed.

      I did kind of cringe though, at the bit about good var naming. I have been known to name vars things like ArthurKingOfTheBritons and IckyIckyIckyPtangZoomBoing when a var is used just once or twice and is declared in close proximity to where it's used, but of course we all know that's bad practice.

      --
      blah blah blah
    7. Re:Who wrote that article? by dvice_null · · Score: 5, Funny

      I think all Slashdot readers should read that article. After all it tells you how to write good _comments_.

    8. Re:Who wrote that article? by Bravoc · · Score: 2, Funny

      Cool!

      Write an article, anonymously post it to /. in the form of a review, get a billion hits. "Look boss, my article is so popular, it got a billion hits!"

      Demand raise for being a popular columnist

      I gotta remember that one.....

    9. 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.
    10. Re:Who wrote that article? by spidweb · · Score: 5, Informative

      A brief defense from the person who wrote the article.

      The indenting in the selected code was not mine. It got screwed up somewhere between my machine and being posted on their site. I'll drop them a not and ask them to fix it.

      No, I am not insane. :-)

      --
      - Jeff Vogel
      Spiderweb Software
      Fantasy RPGs for Mac and Windows.
      http://www.spiderwebsoftware.com
    11. Re:Who wrote that article? by Anonymous+Brave+Guy · · Score: 3, Informative

      Very little apart from failing to respect scope and not encoding any type information?

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    12. Re:Who wrote that article? by ThePromenader · · Score: 2, Insightful

      Although based on advice that would seem rather obvious (one should think) to a more experienced coder, in all it is a good article that will provide food for thought for anyone still learning or tired of wrangling through code. I don't see what microsoft has to do with anything contained in the article.

      I have the misfortune of having two trades - photography and graphic/web design/development - and I can say that when I return from a location to pick up coding where I left it three days before, it sometimes takes me several hours to fully comprehend/remember and reconstruct all the already completed processes in my head so I can move forward. Much of the article's seemingly obvious lessons I only learned through time, so perhaps it will save some of the same (and a few headaches) for another just getting into the trade. The coding one.

      --

      No, no sig. Really.

      ThePromenader
    13. Re:Who wrote that article? by jguthrie · · Score: 2, Interesting

      You need to read this comment and stop complaining that college is trying to educate you instead of training you. Increasing your general knowledge level is most emphatically not a waste of your time and money. What's a waste is having an opportunity to access all kinds of knowledge (most especially knowledge that doesn't have anything to do with your major--you'll find that employers encourage gaining knowledge in your field, but won't let you study interesting but unrelated stuff) and not taking advantage of it to learn all kinds of cool stuff. What's wrong with you?

    14. Re:Who wrote that article? by markov_chain · · Score: 2

      The US education system needs a major revamp.

      Are you kidding me? The college-level system in the US is the best in the world! If anything the high school system needs some improvement.

      --
      Tsunami -- You can't bring a good wave down!
    15. Re:Who wrote that article? by redcane · · Score: 2, Interesting

      Being worth billions is definitely *not* my goal in life. Being able to pick up work easily and without stress is. Having a degree certainly helps the latter goal, but not necesscarily the former.

  2. Damn by ReidMaynard · · Score: 5, Funny

    Damn, that game looks sweet. Anyone know what it is?

    --
    -- www.globaltics.net

    Political discussion for a new world

  3. The whole article is -1 redundant. by rah1420 · · Score: 2, Insightful

    Comments, clarity, constants. If you're not doing this in your daily coding exertions, you deserve to have to maintain your own stuff 10 years from now.

    I have. It ain't fun. Not that I'm bragging on myself, but I've now had people from the support group stop me in the hall and compliment me on the quality of the code I've written and deployed.

    --
    Mit der Dummheit kämpfen Götter selbst vergebens.
    1. Re:The whole article is -1 redundant. by Anonymous Coward · · Score: 3, Informative

      I am trying to maintain code written by a senior designer (logic code). This developer did not believe these rules. It is hell. This is not redundant.

    2. Re:The whole article is -1 redundant. by jstretch78 · · Score: 3, Funny

      I agree, but could all those hours of puzzling actually improve your ability to understand poorly written code? I've been using comments sparsely for years and have spent much time fustrated. But I've found that I can 'See the Code' like on the Matrix and bend spoons and shit.

  4. 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 Sax+Maniac · · Score: 4, Interesting
      Right, I laughed at that #define remark, it's so green.

      The real thing is to used named constants where it makes sense. #define is the crudest approximation of that, C can use enums, C++ can use "const" for compile-time values, etc.

      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.

      In a real project, your constants will often have interdepedencies on other bits of code, so changing one will frequently affect the others. Heck, maybe changing one will cause it not to compile. This example makes them all trivial to the point of uselessness. Shuttling it off miles away in an #include file, can frequently give the impression this than can be changed with no effect on anything else.

      --
      I can explanate how to administrate your network. You must configurate and segmentate it, so it can computate.
    2. 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?
    3. Re:That was just terrible... by Coryoth · · Score: 3, Interesting

      1.) Use test driven development I'll go you one better. Use specification driven development. That is, use a combination of contracts an unit tests. If your method has general constraints, or your object has an invariant, write it into the code using contracts (and ideally use a system that will let your subclasses inherit contracts, and allow contracts to be sucked up and included in the API documentation); if your methods specification is only easily expressed as a set of mappings from input to expected output, write a unit test instead. When you run your unit tests the contracts will automatically get tested too. Better yet, by using contracts you can help yourself on:

      2.) Write complete unit tests, including bad input by using the contracts as a test oracle and passing in randomly generated data to really flesh out the corner cases. In some cases you can do this in a purely automated fashion at the push of a button. Contracts also have the benefit of: (1) not requiring the biolerplate code of unit tests, so they're faster to write; (2) respecting inheritance which can save you a lot of extra test writing. You can't always easily write contracts for methods, and in those cases unit tests make sense, but you may as well take full advantage of contracts for the parts that can be handled in that manner.
    4. 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
    5. 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

    6. 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.
    7. Re:That was just terrible... by swillden · · Score: 3, Interesting

      The real thing is to used named constants where it makes sense. #define is the crudest approximation of that, C can use enums, C++ can use "const" for compile-time values, etc.

      That was my thought, too. When writing C++, you should *avoid* #define like the plague. In fact, avoid using the preprocessor for anything except including (and guarding) headers and, occasionally, conditional compilation. One of the best things about enums is that they create not just values, but *types*. So, if you define:

      enum AlienCount { MAX_NUM_ALIENS = 20 };
      enum PointValue { POINT_VALUE_FOR_ALIEN = 10, POINT_VALUE_FOR_SPACESHIP = 30 };

      void givePlayerSomePoints(PointValue points);

      The compiler will barf if you accidentally type:

      givePlayerSomePoints(MAX_NUM_ALIENS)

      ... or something equally silly, but perhaps less obviously wrong.

      Smart C++ programmers find ways to get the compiler to point out their mistakes. One of the most powerful (and most clever) examples of this is in Barton and Nackman's book on C++ for scientists and engineers. They make use of templates to define types for representing physical values that not only have units attached, but which allow the compiler to statically check the units. Given:

      Mass m = 4 * kg;
      Acceleration g = 9.8 * meter / (second * second);
      Force f;
      f = m; // Generates a compile error!
      f = m * g; // No error here

      The compiler would take care of all of the unit checking at compile time, and, assuming we got rid of the erroneous line, generate machine code equivalent to:

      double m = 4;
      double g = 9.8;
      double f = 39.2; // No need to delay the multiplication to runtime.

      And if m or g aren't actually used except to calculate f, the compiler will optimize them away completely.

      I used the verbose version of their syntax, BTW. You can also write:

      Mass m(4);
      Acceleration g(9.8);
      Force f = m*g;

      which will apply default units to the numeric values. Of course, good code would also define a "const Acceleration g(9.8)" in a header somewhere, etc., rather than using numeric constants directly in the code, and it would use better variable names.

      Of course, such usage is well beyond the "Introductory" level of this article, but I think even an introductory article on C++ should recommend using enums to define constants, not #define. More advanced C++ users should devote a little time to writing classes that idiot-proof the code (because we're *all* idiots, at least some of the time), ideally without sacrificing performance.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    8. Re:That was just terrible... by dkf · · Score: 2, Interesting

      I should have noted why I think that Ravioli Code is a bad thing (and hence that those who think it is good style are doing a disservice to their trade). The problem is that it tends to lead to functions (methods, etc.) without true coherence, and it often leaves the code to implement even something fairly simple scattered over a very large number of functions. Anyone having to maintain the code has to understand how all the calls between all the bits work, recreating almost all the badness of Spaghetti Code except with function calls instead of GOTO. It is far better to ensure that each function has a strong consistent description (e.g. "this function frobnicates the foobar", which you should attach to the function somehow - in C, by a comment because there's no stronger metadata scheme) rather than splitting it up into smaller pieces ("stage 1 of preparing to frobnicate the foo part of the foobar", etc.) with less coherence. The principal reason why this is better is precisely that it makes the code easier overall to understand.

      This is not to argue against splitting functions where necessary; sometimes you need to split things in odd ways with tricky internal coherence to make other parts of the code much neater, and sometimes it improves separation of concerns (a good thing!) But splitting stuff into ultra-short functions for its own sake is missing the point, and those who do it are making big headaches for the maintainers of that code. I say this from a position of authority; I've had to maintain applications I wrote several years after believing them obsolete and setting them aside (yes, with a total hiatus in-between) and I know for sure that understanding the code is the biggest challenge of all for maintenance. People who deliberately split code up into ravioli, and especially those who advocate that others do so, are "dangerous idiots" precisely because they've lost sight of the fundamental need for comprehensibility and are encouraging others to also stray from The True Path.

      Writing good code takes good taste, and any basic technique should be applied judiciously. It's the higher-level things (comprehensibility, separation of concerns, consistency) that are the true goals of the Good Programmer.

      [Ye gods! This message is preachy. Serves me right for posting really late...]

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
  5. 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."
  6. Summary: Beginners need tips too. by Palmyst · · Score: 5, Informative

    The article is suited for beginning programmers, I guess. Here is the summary of the tips.

    1. Comment smartly.
    2. Name your constants ("use #defines").
    3. Descriptive variable names, but not too long.
    4. Handle errors.
    5. Avoid premature optimization.
    6. Clarity is better than cleverness.

    The author may not be a beginning programmer, but it appears that he might be a beginning writer on programming.

  7. In Soviet Russia by quarrelinastraw · · Score: 2, Funny

    In Soviet Russia, code destroys YOU!

  8. Expected Value by dcollins · · Score: 5, Funny

    "One minute spent writing comments can save you an hour of anguish."

    However, what's the probability that the savings actually goes to *you* and not a coworker competing with you for a promotion, or someone who replaced you in a later year? If you work in an office with 100 staff, let's say 1%. So expected savings to you is EV = 1% x 60 minutes = 0.6 minute, less than the minute it takes to write the comment. (Even assuming the payoff is correct, and then helping competing coworkers doesn't do any damage to you.)

    This is what I consider to be the "tragedy of the commons" for software engineering jobs. When I was a programmer, the people who did the least documentation were the fastest, and often the only folks who could approach certain parts of code, and so held in the highest esteem by the executives. Now I only write code for my own projects.

    --
    We know where leadership by an anti-intellectual "strongman" who scapegoats minorities and likes boisterous rallies goes
    1. Re:Expected Value by jfengel · · Score: 2, Insightful

      This is also one of those "Check mark: $1 Knowing where to put it: $49,999" problems. It takes you a minute to comment a function... times 50 methods a day... times the 1% of comments you ever actually need to go back and read.

      Suddenly that "one minute" is a lot of hours spent writing comments that you'll never read, cluttering up your code and getting wronger as you don't maintain them.

      If I knew which comment to write, sure, I'd write it. And I do, when I think it's appropriate. There are plenty of times I wish I'd commented something, but they're way outweighed by times I didn't bother. Good function and variables names are more important to me.

      If you can't come up with a good name, refactor until you can. A unit of code should do something coherent and easily describable, preferably until you don't need a comment.

      Yeah, you'll have to document dependencies, but you should keep them as few as possible. A good language decreases dependencies. I don't have to write "I expect you to free the space for this string" or "This string is stored in a static; do not reuse" because I write in Java.

    2. Re:Expected Value by moderatorrater · · Score: 2, Insightful

      I'm with you. Almost every time I commit to commenting more, I can't find things to comment that aren't obvious in the code. In 90% of the cases, the code should either comment itself or be rewritten.

  9. 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 ZorbaTHut · · Score: 2, Informative

      Fair enough. His post was talking about C++, and I'm a C++ coder myself, so I wasn't aware of the weird C problem.

      I guess if you're forced to use pure C, it could be an issue, but I would personally just compile it as C++ (remember, you don't have to use all the C++ features if you don't want to.)

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

      Why "must"? Almost all C code compiles fine as C++ code, and the few things that won't (generally involving implicit casts to void*, as I understand it) aren't too hard to fix.

      I mean, unless you're using K&R C, in which case I feel very sorry for you.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    3. Re:Mostly agreed by ZorbaTHut · · Score: 2, Informative

      In fairness, I don't actually use assert() - I have my own macro that I use that is turned on in both debug and release mode. But in effect it's an assert() that always runs.

      You're right, though - that's one of the more annoying "features" of assert. Luckily assert() is not a particularly hard thing to rewrite.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    4. Re:Mostly agreed by ZorbaTHut · · Score: 2, Informative

      Since the compiler knows that the int can't ever change, the compiler can easily inline it, giving you exactly the same performance as #define. I believe that most compilers only bother allocating space for the int if you try to take the address of it in some way.

      I suspect they only do this in release mode, of course.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    5. Re:Mostly agreed by drxenos · · Score: 2, Insightful

      I use C++ for embedded systems all the time (along with C and Ada). Compilers will "inline" constants just as well as #defines are. By "symbol table" I assume you are talking about the global symbol table used by the dynamic link-loader. Since constants are local by default I would not worry about this, as they will not appear in the table. And don't listen to the commenter saying you should use C instead of C++ for embedded systems. That's just know-nothing nonsense.

      --


      Anonymous Cowards suck.
    6. Re:Mostly agreed by ZorbaTHut · · Score: 2, Informative

      I disagree. Anything that you expect to happen shouldn't be caught by assert(), of course - hard drive out of space, timeout connecting to website, etc etc etc. But anything you don't expect to happen you obviously can't plan for, and that means you can't guarantee that your program will be in a consistent state. The best thing to do there is to save any user data you can and kill the program.

      Obviously it's best if none of your asserts ever trigger, but I'd rather an assert trigger and save my work before crashing than have my document get increasingly corrupted until I can't even load it to save whatever is left.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    7. 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.

    8. Re:Mostly agreed by AuMatar · · Score: 2, Interesting

      In most C++ libraries, assert is conditionally compiled to noop in non-debug builds. So the same issue applies. That doesn't mean don't use asserts, it means that assert statements should not have side effects.

      --
      I still have more fans than freaks. WTF is wrong with you people?
  10. 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;

    1. Re:I thought #defines were deprecated in C++ by Phisbut · · Score: 2, Informative

      Neither offer any advantage over the other since changing either will only affect the program after its been recompiled, its just that slight disadvantage for a distinct data type.

      Using const int instead of define can save you a whole lot of time when it comes to debugging. When something has gone wrong and you need to step into your code with a debugger, const int will have created a symbol that your debugger can use and inform you of, while define will make the debugger tell you the value of the constant, but not where it comes from or what it's called.

      --
      After 3 days without programming, life becomes meaningless
      - The Tao of Programming
    2. Re:I thought #defines were deprecated in C++ by EvanED · · Score: 2, Informative
      That is bad in a way because the const ints are being stored in memory instead of hardcoded at compile time.

      Not necessarily. That's implementation dependent, and as long as you're compiling with optimization, you're probably wrong most of the time.

      Neither offer any advantage over the other since changing either will only affect the program after its been recompiled

      #defines have a number of well-known drawbacks that consts don't.

      1. CPP macros stomp all over your namespace. For instance, Linux defines a macro "current". At one point I tried to make a local variable in a function named "current". I spent the next 15 minutes swearing at GCC for not compiling my code and giving error messages that made no sense. You can reduce this problem by naming conventions (for instance all caps), but consts don't have this problem at all.

      2. consts don't suffer from order of operation issues, so you can define them without regards to those thoughts. The classic example is

      #define SIX 1 + 5
        #define NINE 8 + 1
        printf("%d", SIX * NINE)
      Which helpfully prints "42" instead of 54. Again, there are ways to work around this (put parens around the expressions), but you don't NEED to work around it if you use consts.

      3. consts are typesafe

      Of course, you can't always use 'const' in C. For instance, you can't use a const int as an array bound. But if you don't have to worry about C compatibility, I can't think of a reason to use #define instead of const for defining constant expressions.
  11. Invariants by ljw1004 · · Score: 2, Insightful

    The comments I like best are correctness invariants or induction hypotheses. Like the ones you'd use to prove that your algorithm is correct. For example:

    // Invariant: if an object is ReadOnly, then everything that points to it is ReadOnly
    // Invariant: if an object is writeable, then everything it points to is writeable
    // Invariant: when you call CopyOnWrite(), you get back a writeable object
    // Invariant: The ReadOnly flag starts false, and will change to true during the object's lifetime, but can never change back to false.

    The correctness invariants for a data structure can also be embodied in a "sanity_check()" function for that data structure, and also in test cases. But the correctness invariants for an algorithm are rarely embodied in any code anywhere. But they're the ones that give you the programmer an assurance that your code is correct. That's why they're so important.

  12. At this point I am thinking by dfuhry · · Score: 4, Funny

    Wow. That was a big waste of time. All of this stuff is obvious and everyone knows it. Why did anyone write all of this?

  13. Actually by Dachannien · · Score: 4, Funny

    Actually, it's not necessarily a bad thing for your code to destroy you. Just make sure you don't dereference any old pointers to you afterwards.

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

    1. Re:It was fine... by Erasmus · · Score: 2, Informative

      I see where you are coming from. These are simple rules and are really important to professional programmers. But at least in my experience, a lot of the kids just entering the field are comping out of their college comp sci programs with chiefly academic programing experience. They know how to knock out programs that solve very specific problems to meet to requirements of their course but which are never used again. Whether that's tragic or not, I don't know. But that is what I've seen in the past.

      Personally, I don't think it's such a big problem. Nice, little articles like this one help and, honestly, most bright people get with the program once they see how the post-college world works. Those who don't tend to get converted the first time they have to deal with someone else's messy code.

  15. But C doesn't have classes or methods. by wiredog · · Score: 5, Funny

    It has functions...

    1. Re:But C doesn't have classes or methods. by neutralstone · · Score: 2, Informative

      "Heck, C++ was just a C pre-processor."

      Please note the term "C pre-processor" can be very misleading in this context; it is not the best term to use when referring to Cfront.

      Cfront parsed, analyzed & type-checked C++ code and generated the equivalent C code. It fits the formal description of a compiler and should be referred to as such.

      I understand that "C pre-processor" can mean "a compiler whose target language is C", but usually it means "the program (or a component of a C or C++ front end) that processes directives beginning with '#' and resolves macro expansions."

      And calling Cfront "just" a C pre-processor is even worse. It was as complicated as any native-code-generating C++ compiler of its later years (when such compilers started to appear on the market), with the exception that it generated C code instead of native assembler code.

  16. 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
  17. If I understand correctly by Ambitwistor · · Score: 4, Funny

    To keep my code from destroying me, I shouldn't #define MAX_ALIENS_ON_SCREEN_AT_ONCE to equal 100. That's way too many aliens to survive.

  18. 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>
  19. Basics by Joaz+Banbeck · · Score: 2, Insightful

    Ok, yeah, it's redundant. But is there anything wrong with going back to the basics? Look at sports figures ( and I chose sports for an analogy because most pro sports are very good at filtering out all but the best, and the very best get to the top by proving that they are better than the second best in head to heah competition, something that programmers almost never do. ) The best often are known for continually going back to basics.

    Lombardi was known for his comment that if you block and tackle better than the other guy you win.

    Magic Johnson was known for being on the court an hour earlier than the other pros and practicing shot after shot.

    And Bobby Fisher's guide for beginners is still the best because he knew the basics like nobody else.

  20. Steps for Job Security by Mr+Pippin · · Score: 2, Funny

    Yep, no you need to include the "Back To School" basic programming techniques, like Rodney Dangerfield might include.

    1. Use comment syntax to obfuscate the actual running code
    2. Don't indent or "pretty format" your code
    3. Use the same variable name over and over, capitalizing different letters to make them unique throughout the program
    4. Use variable names that are incredibly offensive in hindu, so any common "outsource" programmer will refuse to work on the code.
    You get the point.

  21. Re:Self documenting code? by Lord+Bitman · · Score: 4, Funny

    except friday.. I want to go home. I'll clean it up on monday.

    --
    -- 'The' Lord and Master Bitman On High, Master Of All
  22. Noooooooooo by Anonymous Coward · · Score: 2, Funny

    In Soviet Russia, Code comments YOU!

  23. 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
    1. Re:Felt I should point out by 19thNervousBreakdown · · Score: 2, Informative

      First off, it's not a side-effect. It's intended.

      I know it's nothing more than syntactic sugar, but making a temp variable, worrying about scope and naming clashes, messing up your code, having to pull stuff out or put stuff into a for loop, and all the other million ways it comes in handy says you're cutting off your nose to spite your face. I have to reiterate: if this is too complicated for you, you shouldn't be writing C. Then, when we start to talk about C++, forget about it. Template magic, function and operator overloading, virtual functions, etc. are all way more complicated. For that matter, pointers in C is just one thing I can think of that's far more complicated than the difference between pre- and post-increment.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  24. 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
  25. Two rules to live by by kabdib · · Score: 4, Funny

    Rule #1 of Systems Programming: Never check for an error you don't know how to handle.

    But, if you simply MUST, then:

    Rule #2: If you have to blow up, arrange it to be in someone else's code.

    That way, when you're (say) deep in your file system update locking and you realize that something's gone truly plonkered, you stealthily return something that causes X Windows to blow chunks long after you've returned.

    "It's the file system."

    "No, it's not. It's the bloody clipping code in X. Remember when release 10.5.08A came out? It's just gotten worse from that. Did I ever tell you about the time that 9.02 was released? Let me just say, you're lucky, man . . ."

    Rule #3: When necessary, distract, distract, distract. Everything is on the table, and "Look, the Goodyear Blimp!" [points excitedly] is just for starters...

    Good systems programmers know these tricks, and all the others you haven't learned about yet, which is why they're curmudgeons with level 70 pallies and tier-2 gear and you're shovelling Java and XML around trying to make a rent check.

    Cheers!

    --
    Any sufficiently advanced technology is insufficiently documented.
  26. Tip 3 is crap. by geekoid · · Score: 2, Insightful

    " For example, in real life, I probably wouldn't give constants names as long as I did in the previous section. I just did that so that you, the reader, would totally understand what they meant without any context. In the context of the program itself, instead of:

    #define MAX_ALIENS_ON_SCREEN_AT_ONCE 5
    I would almost undoubtedly write:

    #define MAX_NUM_ALIENS 5

    Any confusion caused by the shorter name would be cleared up very quickly, and the shorter name would lead to much more readable code. "

    Cleared up very quickly? no, it can only be cleared up after searching your code to realize it is the max number of aliens on the screen, not the max per level, or per game, or whatever the hell you were thinking 2 years ago when you wrote it.
    Bad Bad Bad.
    sloppy.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  27. Simple really by riskeetee · · Score: 2, Funny

    Don't deploy your code to the ED-209.

  28. *ahem* by Greyfox · · Score: 2, Insightful

    /* * Maximum number of aliens on the screen at once */ #define MAX_NUM_ALIENS 5

    --

    I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

  29. Simple Enough by vimh42 · · Score: 2, Funny

    First of all. Don't write a program called MCP. Second, don't work for a company called Skynet.

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

  31. Whipping accountants and CEOs by geek2k5 · · Score: 2, Insightful

    It may be a dead horse to good coders but it is essential that the accounting staff know such things. Such articles can be used to educate them. The articles can also be used to train the newbies they hire.

    Unfortunately, there are organizations where the bean counters and CEOs want results NOW and don't want the staff to 'waste' their time on documentation and good coding practices. If you can get your quick and dirty code completed for that 'one time' application up and running really fast, they will love you for it and the effect it has on the bottom line. If you insist that documentation and special good coding refinements are needed and it will take half a day longer, they'll tell you not to waste your time.

    Then, a month or a quarter or a year later, they will ask you to take that 'one time' application and modify it for slightly different parameters. And because you did it before, they will expect it to be done in a fraction of the time.

    It is an endless treadmill with some organizations. While doing the right thing usually costs less in the long run, getting the results NOW often overrules doing the right thing.

  32. 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."
  33. A Note From the Author by spidweb · · Score: 5, Informative

    As the person who actually wrote the article in question, I'd like to thank you for your comments and respond with a few of my own.

    * To those who think it is all so obvious that I shouldn't have written about it:

    No. You are wrong. Just wrong. Good programming practices do not just appear in peoples' heads as if by magic.

    It's an introductory article. It's sold as an introductory article. And I am far more interested in being Right than I am scared of being Obvious.

    * To those who have problems with suggesting using #define instead of const int

    Meh. Yeah, you're probably right. But the important thing here is the CONCEPT of having your constants being defined in one central, easy to find place. Once a person has that down, he or she can define them however is desired.

    * To those who accuse me of being a (gasp) inexperienced programming writer.

    Yeah. So what? I never said I wasn't. I'm a game author. I've written over a dozen games. They all made money. That doesn't mean I am mister programming advice god.

    But one, if you have a problem with it, yell at IBM, not me. They're the ones who had me write the piece.

    Two. This is kind of ad hominem. Who cares how experienced I am or am not? I'm still right.

    * I didn't read the article, but I'll say bad things about you because it means I'm awesome.

    R0ck 0n d00d. First post!

    * I liked the article. It might tell beginning programmers something actually useful.

    If anyone says this, thanks in advance.

    --
    - Jeff Vogel
    Spiderweb Software
    Fantasy RPGs for Mac and Windows.
    http://www.spiderwebsoftware.com
    1. Re:A Note From the Author by tagattack · · Score: 2, Insightful
      I appreciate your effort(s) to improve the quality of code in general. It's a noble goal I've spent my entire career trying do, including mentoring co-workers and junior level engineers as well as writing papers, and a lot of preaching and ranting...

      But part of the problem I saw when I read your article is that your suggestions really aren't that good. Take for instance your example of "good" comments:

      // This procedure moves the bullet upwards. It's called
      //NUM_BULLET_MOVES_PER_SECOND times per second. It returns TRUE if the
      //bullet is to be erased (because it hit a target or the top of the screen) and FALSE
      //otherwise.

      That comment is actually documentation, and if you are going to document in comments (not *entirely* a bad idea) then you should be actually using a type of comment designed to be picked up by some documentation system, such as autodoc.

      Describing what your code does is the job of documentation, describing why your code does what it does the WAY it does is the job of comments.

      Boolean player_bullet::move_it() /* <- move_it is kind of a crummy name */
      {
      Boolean is_destroyed = FALSE;

      // Calculate the bullet's new position.

      An example of just saying what you're doing instead of why you're doing what you're doing.

      [Small chunk of code.]

      // See if an enemy is in the new position. If so, call enemy destruction call and
      // set is_destroyed to TRUE

      [small chunk of code]

      // See if bullet hits top of screen. If so, set is_destroyed to TRUE

      [Small chunk of code.]

      // Change bullet's position.

      Why do we need to say that this changes the bullets position?
      Shouldn't the code probably look like, bullet.setX(x); bullet.setY(y); or some variation thereof and a redraw? Wouldn't that indicate that the code is moving the bullet? Do we really need a comment to say this?

      [Small chunk of code.]

      Return is_destroyed;
      }

      In retrospect, a good time to use a comment is when you deviate from anything a future onlooker would be expecting from your method, function or subroutine. For instance, where you would do something specifically because of another bug that or behavior that is out of your control.

      /* We cannot add the events immediately or they simply will
      * fail to work. Event's on un-rendered nodes are
      * optimized away. But these nodes will be rendered when
      * this operation is finished, so a single cycle delay will
      * make sure we let this thing render before attaching
      * events.
      */
      window.setTimeout( function () {
      self.populate(child)
      }, 0 )

      A smart person doesn't need to remind himself what code X does, unless it's not obvious.

      this.y = y
      this.x = x

      ...That's pretty obvious

      In the section where you suggest using define a lot, I honestly consider that a particularly bad idea. Using global constants is just in general a bad practice. A good practice, on the other hand, is having all arbitrary static data be a matter of configuration. That is, instead of defining NUM_ALIENS_TO_KILL_TO_END_WAVE as a compile time constant, or any other form of literal, define it in a configuration file so it can easily be modified without a code change.

      Enabling behavioral changes without code changes is critical to software success. Every time you change code, you rebuild and redeploy things. And this provides the potential for other

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

  35. What did we do to deserve our time wasted this way by Livius · · Score: 2, Funny

    No, this has to come from no less than Field Marshall Obvious.

    "Comment like a smart person."

    Let's all "program like good programmers" while we're at it, or, even better, "invest like lucky investors", "dance like a professional", "socilize like an extrovert", "copulate like leporids", "wield power like a super-villan", and "fly like Superman".

    Besides, nice idea in principle, but based on two grievously flawed assumptions: the programmer is a smart person, or at least knows what one is like, and the next programmer reading it will be a smart person.

  36. MOD PARENT UP by Deef · · Score: 2, Insightful

    I've tried this both ways over the years, and in my experience, separating large functions into small, well-named ones with clearly delineated inputs and outputs is a big net win for maintainability. It makes it much easier to see what is going on, because it doesn't force someone reading the code to have to confront the whole mess at once. They can dig deeper into only the subfunctions that are relevant to the problem that they are trying to solve, without worrying that some non-local effect of a prior block of code will confuse the issue.

  37. Re:Good ideas, bad execution by 91degrees · · Score: 2, Interesting

    Re. file scope: if you can figure out where to put function prototypes and const definitions such that they'll be visible in the right places, how is appropriate placement of macro definitions any harder? They go in the same place.

    I tend to put a lot of my consts within a class or function. You can sometimes do this with #define and #undef but it's less clear what you're doing. And even if you do this, you need to be a lot more careful about namespace pollution. C++ will allow the scope to be limitted to a namespace.

    Though you do still have to be careful about passing in expressions that have side-effects (because you don't know how many times they will be evaluated), or that are expensive to compute (inefficient for the same reason).

    This is a concern as well. But unless you need to use the paste operators, a macro doesn't have any benefit over a function. With a function, it's a lot clearer what the code does.