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

486 comments

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

    Captain Obvious?

    1. Re:Who wrote that article? by endianx · · Score: 1, Insightful

      I agree. This is very basic stuff you would learn in Intro to Programming, or in any other article on the subject. Nothing new here.
      I highly recommend a book called Code Complete. It is kinda pricey and, yes, it is by Microsoft, but I found it to be both helpful and thought provoking.

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

    3. Re:Who wrote that article? by efence · · Score: 1
      Right at the end of the article:

      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.
      You can pat yourself on the back now.
    4. 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();
      }

    5. 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.
    6. Re:Who wrote that article? by Swizec · · Score: 1, Insightful

      You'd be surprised by how many programmers who have gone to actual rpogramming classes fail at anything as simple as indentation. Peopel jsut aren't taught this at school so either they are wise and learn it themselves or they read somewhere about how to code like a human being and not a thousand monkeys on typewriters.

      The article may be redundant to many, but I can name at least twenty people off the top of my head taht should give this a long hard read and then read it again.

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

    8. Re:Who wrote that article? by Anonymous Coward · · Score: 1, Interesting

      About the author Jeff Vogel Since 1994, Jeff Vogel has run Spiderweb Software. He has written a dozen or so fantasy role-playing games for Windows and Macintosh, including the award-winning Exile, Avernum, and Geneforge series. He is the author of The Poo Bomb: True Tales of Parental Terror and other humorous writing. He lives in Seattle. sorry i can't get information about any special power
    9. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      What? That all seems very orderly to me. Braces on one level, code on another. Nothing wrong with that. If you're crazy.

    10. 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.
    11. Re:Who wrote that article? by Tofystedeth · · Score: 1

      Wow. I didn't even check to see where he worked. I played the heck out of a lot of those Spiderweb shareware games. The gem mining puzzle game was awesome, and really hard at times.

      --
      "A little knowledge is a dangerous thing. Drink deeply or not at all."
    12. 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
    13. Re:Who wrote that article? by iago-vL · · Score: 1

      As soon as I saw "Jeff Vogel", I knew I had to read the article. The Exile series is still my favorite series of games ever made. Avernum, however, I didn't like so much.

    14. Re:Who wrote that article? by umghhh · · Score: 1

      SInce begin of my time as an engineer (yes I work with software and I am an egnineer) I meet people some intelligent some not so who do not know these basic rules and if confornted with them refuse to cooperate thowing some excuse like time pressure or their perfectness in coding etc. I laugh every time. Some of these bastards have balls to tell me that their code is not faulty although there are sufficient evidence to the contrary.

    15. Re:Who wrote that article? by DrLov3 · · Score: 1

      It's my code, I created it, I can sure as hell destroy it !!! and not the other way around.

      No seriously when was the last time you heard of suicide by uncommented VB 4 code. A programmer's grammar and synthax will kill him long before his own code.

      Ho! and ... I for one, welcome our new uncommented, un-self-explanatory-genious JAVA lines of code overlord just in case :P

    16. 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_.

    17. Re:Who wrote that article? by Anonymous Coward · · Score: 1, Insightful

      I suspect that was a formatting error on the part of the people who put up the web page.

    18. Re:Who wrote that article? by maxume · · Score: 1

      I can pat myself on the back whenever I want.

      --
      Nerd rage is the funniest rage.
    19. 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.....

    20. Re:Who wrote that article? by JimDaGeek · · Score: 0

      Not to sound like a Troll, however, I have been a programmer for more than 12 years. I have worked with many different languages. I can say for certain that this article should be required by every VB and COBOL programmer in the world.

      I have never met a group of programmers less competent than some of the "VB only" "programmers" I have had to work with. If the topic doesn't deal with kiddie stuff like connecting to a DB and grabbing a few rows of data, most VB-only people I have personally worked with are totally lost. Sure, most VB-only dudes can throw together a cheesy "click button, do X" type of program. Call me when VB is a real dev. language. No, VB.Net doesn't cut it IMO. It is still too juvenile and overly verbose of a language IMO. C# was made for .Net. If you cannot understand and program in C#, well IMO, you should be on some assembly line or something, certainly not a "programmer".

      Now cue all the VB-only dorks that want to support their position. Hey, here is a question, why not learn to program in more than just VB? I have never met a real programmer that know languages like C, C++, Java, C#, etc that would "rather program in VB". It just isn't the case. So any VB "programmer" that says they can program in other languages is just talking out their @ss.

      Once someone learns to be proficient in any language other than VB, I am willing to bet they wouldn't want to touch VB again.

      Cue the VB-only "programmers" that now say, "I can program in x, y and z. However, I think VB is the bestest ever!!!". Yeah, your type won't be hired by the programming group I work for. Thank God.!!!!

      --
      General, you are listening to a machine! Do the world a favor and don't act like one.
    21. Re:Who wrote that article? by JimDaGeek · · Score: 1

      Well, to be fair, not everyone that has excelled in life had gone to a university. Heck, Billy G. and Steve J. both dropped out of university and both are worth billions (USD)!

      There is also the problem of which university you go to. Not all CompSci courses are made equal.

      Oh, and there are also those that are very smart that get very bored by some of the universities curriculum. I remember when I was in college, I had to take all kinds of crap course for a CompSci. degree. Those course had nothing to do with my major. They were a waste of time and most importantly, a waste of my money.

      I would love to see discipline specific courses at universities. Why the hell should I spend my money on American history, when I am an EE major?

      The US education system needs a major revamp. The beginning of 11th or 12th grade, students should learn about specific job functions. Find out what each students wants to do, and get them on a "fast track" to that career. Why spend 4 years in college when not all of those 4 years are spent learing about the job function you want to do with your life?

      OK, I am off my soap-box now :-)

      --
      General, you are listening to a machine! Do the world a favor and don't act like one.
    22. Re:Who wrote that article? by penrodyn · · Score: 1

      You obviously didn't read the article, check the conclusion paragraph and the third line of text. Your comment suggests you are the kind person who needs to read such an article, it is the obvious that we tend to miss, and you just fell right into the trap.

    23. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      Obvious yes, but most people can't even follow simple rules. I'm dealing with a huge system that breaks most rules - above all proper commenting. How's a 1200 (yes, twelve hundred) lines long procedure with next to no useful comments, for starters? I better stop here or I'll end up writing a novel.

    24. Re:Who wrote that article? by Tofystedeth · · Score: 1

      Yeah, Avernum I played for a couple days, then grew bored of it. Geneforge I played quite a bit one Christmas break when I was at home on my parents computer that had no games on it. Mostly it was the puzzler that I really got a kick out of.

      --
      "A little knowledge is a dangerous thing. Drink deeply or not at all."
    25. Re:Who wrote that article? by blueZhift · · Score: 1

      While it is clearly written at an introductory level, and says so itself, I still find it useful to revisit stuff like this from time to time. It's good to be reminded of what we're already supposed to know and see it from another person's perspective. I may print this out for my son to look at since he's just starting out.

    26. Re:Who wrote that article? by FrankieBaby1986 · · Score: 1

      Being a college student myself, I tend to agree with you, however: There's more to life than being an employee and job skills. Also, taking all Engineering classes can get dull. Last semester I took Philosophy of Love and Sex- quite a thought provoking course. And it was a breath of fresh air, considering a Comp Eng major is probably 80% male at my school and Phil had mostly women in it. Note that's not the major reason i took the class, i took it because the subject interests me, but is not something I would want to make a career out of.


      But the real reason is simply financial. The longer they can keep you in classes, the more tuition you pay.

      --
      ERROR: SIG NOT FOUND (A)bort, (R)etry, (F)ail?:
    27. Re:Who wrote that article? by drew · · Score: 1

      It looks like he originally used a combination of spaces and tabs (ts=8, sts=4 in vim. I know Visual Studio used to have that as the default indentation behavior.) and the tabs got munched by the HTML conversion.

      --
      If I don't put anything here, will anyone recognize me anymore?
    28. Re:Who wrote that article? by chad.koehler · · Score: 1

      Hey man, relax.

    29. 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.
    30. 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
    31. Re:Who wrote that article? by seaturnip · · Score: 1

      Actually though there is very little wrong with using macros for simple numeric constants. They become problematic as soon as any functions or operators are involved (e.g. #define TWO_PI 3.14*2 //bad) but there was no instance of this in his article. I often prefer #define's for constants because they stand out more from the surrounding code.

    32. Re:Who wrote that article? by seaturnip · · Score: 1

      Remind me what VB has to do with anything again?

      Anyway, VB is perfectly cromulent for things like slapping together quick GUI frontends to an already existing application. Popular languages tend to be popular for a reason; it is shortsighted to dismiss any widely used technology.

      I have never met a real programmer that know languages like C, C++, Java, C#, etc that would "rather program in VB".

      So am I wrong in guessing that despite your arrogance you have never learned a language outside of the C family?

    33. Re:Who wrote that article? by fbjon · · Score: 1

      That's great, now lick your elbow.

      --
      True confidence comes not from realising you are as good as your peers, but that your peers are as bad as you are.
    34. Re:Who wrote that article? by insane_coder · · Score: 1

      Well I am insane, so you can take my comments with a grain of salt. For code like that, a return smack in the middle is evil, makes the flow more convoluted. Reverse the condition, remove the return, and now have that first if contain the rest of the code. Looks better in the end.

      --
      You can be an insane coder too, read: Insane Coding
    35. 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.
    36. Re:Who wrote that article? by maxume · · Score: 1

      Inside of the joint is easy. You want 'lick your funny bone'.

      --
      Nerd rage is the funniest rage.
    37. Re:Who wrote that article? by seaturnip · · Score: 1

      Scope: yes this is a reason not to use macros for purely local constants, but not for globals. If you accidentally "shadow" a macro with a local or class variable, an compile error will be produced and no genuine problems will occur. Actually I find this behavior preferable to what you get with global const ints!

      And the substituted number itself contains complete type information. 1 is an integer, 1L is a long integer, 0.0 is a double, 0.0f is a float.

      Sounds to me like you are being pedantic because macros aren't "pretty". Sure, but you can't come up with any pragmatic reasons not to use them can you?

    38. 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
    39. Re:Who wrote that article? by Xiaran · · Score: 1

      Anyway, VB is perfectly cromulent for things like slapping together quick GUI frontends to an already existing application. Popular languages tend to be popular for a reason; it is shortsighted to dismiss any widely used technology.

      I personally think one of the major problems with VB is that it is quite often used for a lot more than slapping together quick GUI frontends to already existing applications. Plus if I wanted to do this myself... unless I *had* to us VB I would do it with something like Delphi.

    40. Re:Who wrote that article? by alexfromspace · · Score: 1

      These code examples are worthy of a first course on elementary computer programming. They even look like they are taken right out of the lecture notes on "commenting your code" for freshmen.

    41. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      I always love how people point that out. But truth of the matter is, Bill Gates and Steve Jobs would've been filthy rich whether they dropped out of school or not. For the rest of us mere mortals, the average person with a bachelor's degree earns over $20k a year more than people with just a high school diploma.

      If you're making money hand over fist without college, congratulations. But for the rest of us, that usually doesn't work out so well.

    42. 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?

    43. 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!
    44. Re:Who wrote that article? by markov_chain · · Score: 1

      you shouldn't rely on programmers knowing basic language facilities like the pre- and post-increment operators in the C family,

      I guess you come from the "if it was hard to learn, it must be hard to use" camp popular in the C++ crowd ;) In the above example, I tend to agree with the author. The fact that a line of code or routine is sensitive to the location of the increment operator tells me that the programmer doesn't write robust code. If I have to add some lines or change the algorithm, I'd be more likely to break either that or some other hidden dependency that result from unclear thinking.

      --
      Tsunami -- You can't bring a good wave down!
    45. 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.

    46. Re:Who wrote that article? by Schlage · · Score: 1
      @Anonymous Brave Guy

      Apart from ... [many examples] ... what was wrong with it? :-) I found your examples interesting, but nearly all of them went over my head.

      I am, of course, being facetious. So, were there or were there not 'gotchas' in the article? Or was your facetiousness a reference to how you were picking apart the article?

      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 ... the only thing worse for inquisitive newbies than no information is bad information. I ask, because I'm one of those inquisitive newbies and if there is a better source for the type of information that this article provides, such as explanations for the examples you cite, then I would greatly appreciate learning where such a thing could be found.

      My problem, and I suspect this is the case for many beginners, is that there is so much available that I don't know what's crap and what's not. Also, it seems that the only way to get alot of this information is to consume and digest mass quantities of books on programming, when it would be nice to have a single discrete source for such things.

      Of course, there's the matter of getting people to agree on what doesn't suck, isn't there... *sigh*
    47. Re:Who wrote that article? by Lost+Engineer · · Score: 1

      What's not robust about it? Or are you from the "no side effects allowed" camp?

    48. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      who cares

    49. Re:Who wrote that article? by achacha · · Score: 1

      I can't agree with you more, I said basically same thing on digg and got -20 diggs for my comment. People do not realize how important early optimization is given deadline creep (notorious in game industry). You never have time at the end to optimize because you are fighting with sales/marketing on what features to cut and what date to meet for optimal sales.

      Many people also mistake optimization for well written code (as in efficient algorithms) and honestly compilers can't optimize a poorly designed algorithm most of the time.

      #define should only be used for constants, macros can make the code very unreadable (especially to novices that this article targets) and thus it should have suggested using a 'static const' instead.

      It should have also mentioned following Doxygen like formatting for comments so that when all is done you can run Doxygen (or any tool that generates comments) and get some API like documentation done. Doxygen style of using /*! */ or //! is supported by many other doc generating packages.

    50. Re:Who wrote that article? by SillyPerson · · Score: 1
      Let me give a second opinion from a professional developer.

      I agree with Anonymous Brave Guys evaluation. However, I still think the articles advice is excellent. For a newbie programmer, I'd only change two (minor) things in it. First, using defines a lot is fine for C, but you don't want to do this in C++. Use constants instead. Second, pre- and post-increments can be quite useful, and are not hard to understand. I'd draw the line of unnecessary cleverness somewhere beyond that (somewhere near heavily relying on operator precedence).

      HTH, Michael

    51. Re:Who wrote that article? by mackyrae · · Score: 1
      He was being facetious by making such a long list. I forget the full list, but from what I remember and my coding experience:
      • Hungarian Notation: that's when the first couple letters of the variable name tell what type it is. It's how I first learned to name things when I started VB. In VB a label for the total number of dollars would be named something like lblTotalCash and the button that corresponded would be btnTotalCash. In C, it's often done that you have dPencils. The d is because in C when it's an int and you want to put it in a printf(), you use %d, so this keeps you from trying to do non-integer operations on an integer (3 / 4 = 0 in integer division, remember?). It can make it easier to avoid having variables all with slightly different names which you can't keep straight (like the label v. button), and to avoid treating it as the wrong data type, but it can be a pain to read if you're not someone who uses it. Thanks to VB, I use it for names of parts on interfaces (makes sense to me, likely to have the same name as most things need a label to be attached to them...radio button....and then the label for it), but I don't use it for backend code. Also, some people prefer variables_that_look_like_regular_words with the underscores acting like the words have spaces. It makes it more English-like. Others use the way I did above--crazyCaps. That's a personal preference thing, but the underscores are probably easier to read.
      • Pre and post position operators: i++ and ++i will both increment i by 1. That's fine on a line by itself. TFA says to not write code that requires knowing the technical difference--so don't use it on the same line as anything else. I tend to agree with that because it does make it harder to read. The technical difference, however, is something you should know in case you come across it. The GP is saying "don't assume, as the author says, that other people won't know the difference because all good programmers do," and that makes sense to an extent. If it won't be that hard to read, why not put it on one line? If your code's complicated, anyone enough of a newbie at programming not to know the difference isn't likely to look anyway (and that line will be the least of their worries). On the author's side though, for maximum readability, setting the incrementing on its own line is most legible for most people. If you don't know what's going on anyway, here's a chance to learn. If a line says "x=y++" that does "x=y" and THEN "y=y+1". If it says "x=++y" it does "y=y+1" and THEN "x=y" (with the new value of y). So if x=3 and y=5, after "x=y++" you have x=5, y=6. After "x=++y" you'd have x=6, y=6.
      • #define: the general idea, yes, agree. When there is a value which you are likely to want to change but will not change during runtime and which applies to the whole program, make it a constant, and make it stand out and be in a place that's easy to find to change if you need to do so. As the article-author did, use ALL CAPS FOR CONSTANTS because it makes them stand out more and easier to find. Like the GP said, though, the pre-processor isn't really necessary. You can just declare it as a constant (I believe it's the keyword "const" in C). In Java it's the keyword "final", for instance "final int SCREEN_WIDTH = 300".
      • Error checking: the article-author is right here. I've had teachers say I don't need to parse strings that are being entered because they won't put in bad data. BS! ALWAYS parse the strings, especially if you asked the person to enter a number. A letter in there would screw it up, and punctuation is really bad. How do you think SQL injection happens? A nice thing about C's pre-processor is that you can use #ifdef & #define. You have a line at the top #define DEBUG. Then all your error-checking stuff happens between lines that say "#ifdef DEBUG" and "#endif". When you are debugging, put in that line at the top that says "#define DEBUG". Your debugging output/tests will then happen so you c
      --
      look! it's a bird, it's a plane, it's....a girl? yes, a girl browsing Slashdot on Linux
    52. Re:Who wrote that article? by Enselic · · Score: 1

      Good to hear :)

    53. Re:Who wrote that article? by mackyrae · · Score: 1

      Given the choice between VB's interface designer and Glade (or Stetic), I'll take VB. It lets you just put things where you want them. Glade gets ornery about how many items are in each other item and whatnot. For the actual programming part of it though? Yeah, I'm with you.

      --
      look! it's a bird, it's a plane, it's....a girl? yes, a girl browsing Slashdot on Linux
    54. Re:Who wrote that article? by gnuman99 · · Score: 1

      I would disagree. The error check is right at the beginning of the function. You get it out of the way first and remove the indent. Indents are what makes code unreadable - they are branches... That's why it was Linus (I think) that said that if your function is more than 3 levels nested, you are fucked anyway - use a new function.

      Code like

      void foo()
      {
            if( blah ){
                  [... 200 lines ...]
            }
      }

      is A LOT less readable than

      void foo()
      {
            if( !blah )
                  return;

            [... 200 lines ...]
      }

      It tells me instantly that blah has to be true or the function doesn't run. It is A LOT easier to see when the next block is executed than suddenly finding yourself on like 160 in first example not knowing if you forgot to close the block or something. The first example is only correct if you have very few LOC (less than a page) or use a seperate function for the true condition as in


      static void foo_gooder()
      {
            [... 200 LOC ...]
      }

      void foo()
      {
            if( blah )
                  foo_gooder();
      }

    55. Re:Who wrote that article? by Bill+Dog · · Score: 1

      That's also been my experience, years ago. Replace all occurences of "VB" with "Java", and you've just described what I'm seeing these days.

      --
      Attention zealots and haters: 00100 00100
    56. Re:Who wrote that article? by iminplaya · · Score: 1

      Top of page

      Level: Introductory

      :-)

      --
      What?
    57. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      There's more to life than being an employee and job skills.

      And you have the rest of your life to learn them. College should be about one very specific thing, especially if you're the one paying for it.

    58. Re:Who wrote that article? by hemorex · · Score: 1

      A means of transport is not a waste of money :: Increasing your general knowledge level is not a waste of money It's not worth being in debt for the rest of your fricking life for a Ferrari :: ???

    59. Re:Who wrote that article? by jguthrie · · Score: 1
      Adding a three hour astronomy course (which I did because I could when I was an undergrad) adds exactly 0 to your tuition and fees if you're already a full time student and the textbooks for 100-level courses are vastly cheaper than those for the 300 and 400 level courses toward your major and can usually be sold back without trouble, if you've a mind to. So, you're talking about $50 at most additional expense. I don't think that you can even buy the right to sit in a Ferrari for $50. And try finding a similar course once you're out in the workplace.


      Personally, I wish I had taken the Arthurian Legends in Film course that I heard of when I was in grad school (the viewing list included everything from "Excalibur" to "Monty Python and the Holy Grail") or the "Love in the Western Tradition" course many of my running buddies took when I was an undergrad. I've been out of school for almost 20 years, and that's where my regrets are.

      Or, look at it another way. While you're in college, you don't have to account for your time. You can do stuff and check things out and you won't have to explain to some HR person ten years later how you could be a worthwhile employee even though you chose to spend a year unemployed. It's not as good as hitchhiking around Europe, but it's a lot easier to explain.

    60. Re:Who wrote that article? by thePowerOfGrayskull · · Score: 1

      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. You'd be surprised. I work with a number of alleged professional developers (at least, they have degrees and have been doing it for years) that think "// increment X by one" is a useful comment.
    61. Re:Who wrote that article? by cgaertner · · Score: 1

      *If* that's not Java and is C, it's not ANSI C. ANSI C requires /* comment */ -style commenting, not // and you're supposed to declare the variable before putting it in the for loop Not true for C99 any longer - it's 2007, times have changed ;)
    62. Re:Who wrote that article? by devnull17 · · Score: 1

      A lot of us have the pleasure of maintaining code written by people who were clearly not even trained to operate a calculator correctly, let alone a computer. If my predecessors had read this article, my job would be so much easier.

      I don't understand it, but a lot of people seem to have trouble with "comment your fucking code."

    63. Re:Who wrote that article? by l0cust · · Score: 1

      Hehe that has to be one of the funniest comments I have read in a long time. So.. how many times did you have to read that article before you came up with that?

      --
      Politicians and Pedophiles: Two groups of exploitive bastards who are most dangerous when they're thinking of children.
    64. Re:Who wrote that article? by An+Onerous+Coward · · Score: 1

      Two counterpoints:

      1) Your first attempts at optimization are often misguided, and add little if anything to the overall performance. If an optimization doesn't improve performance, and makes the code less readable, you've done yourself a disservice.

      2) Something may be necessary to meet deadline, and still not be conducive to writing good, maintainable code. I guess that's less important for games than other applications. Still, at best you're arguing in favor of a necessary evil.

      --

      You want the truthiness? You can't handle the truthiness!

    65. Re:Who wrote that article? by cavemanf16 · · Score: 1

      Great point, but try not to be too harsh on the younger crowd with this mindset. I too was once disgusted with having to "retake" American History, English & Literature, and other liberal arts courses when I got to college because, hey, I already learned that stuff in high school!! (Mind you, probably 80% of most high school grads haven't *actually* learned that stuff by the time they hit their freshman year of college, but that's a different issue altogether.) I thought that college should be more training related, but what I have found out now (after dropping out of college after 3 years, then re-enrolling and finishing my Comp. Eng. degree after working 5 years) is that most high school students are not mature enough yet to go to college straight out of high school.

      Of course, when you're 18 you probably ignore all sorts of sensible advice like "work for a year or two to save up for college" because you're 18 and you know exactly how stupid everyone else older than you is, but this is the reality for most high school students. I should've listened to this kind of advice when I was 18! I would probably already have my PHD by now if I had! Unfortunately, I had to learn this lesson the slightly harder way, and now I've got school loans out the wazoo. :(

      My point is that most students in college probably view all of the liberal arts courses as stupid wastes of time because they only view education at that point in time as a means to an end - namely, making more money than the average US citizen once they graduate. Colleges exacerbate this situation by HEAVILY recruiting every single high school student starting in their sophomore or junior years of high school, so these kids (who are barely old enough to drive a car at that point in their lives) get it drilled into their head that yes, going to college immediately is the best medicine for a successful life. Unfortunately, for 80% of us it's not, and we need to spend just a little time in the "real world" first to find out just how bad life can be without the skills and knowledge obtained by studying broader subjects than what we are particularly talented in doing regardless of that level of education.

    66. Re:Who wrote that article? by AVee · · Score: 1

      I often prefer #define's for constants because they stand out more from the surrounding code.

      When was it they made it illegal to CAPITALIZE constants?

    67. Re:Who wrote that article? by AVee · · Score: 1

      Forget it, it won't help, it's hopeless.

      "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
      .
      That statement was made by Edsger Wybe Dijkstra in 1975. Nothing changed in more then 30 years, a short article on some IBM website will not change things either.

    68. Re:Who wrote that article? by hemorex · · Score: 1

      However, we're still talking about a huge investment in time. I love learning about things that aren't necessarily directly useful, but can rarely justify taking the time to do so. I don't disagree that early in life, such digressions aren't quite the drain, but once you're already out there in the workforce -- especially with mouths to feed and all that -- it's a different situation altogether.
      This is just the opinion of a (proud) dropout, though. Take it for what it's worth.

    69. Re:Who wrote that article? by HouseArrest420 · · Score: 0

      I wonder what mushrooms he were on when he came up with that coding style Well now, that's what is so great about C. Most C programmers I know use varying types of indentation. It's like they get together and say, "Screw indentation, we have curly brackets!"

      >>> print "Long Live Python!"

      --
      This is Slashdot! Give me the latest gadget, bug, or OS project! This ain't english class so don't confuse the two!
    70. Re:Who wrote that article? by mackyrae · · Score: 1

      In that case, gcc needs to have its ANSI handling fixed. I got compile errors using the ANSI flag and // with gcc, but worked fine without the ANSI flag.

      --
      look! it's a bird, it's a plane, it's....a girl? yes, a girl browsing Slashdot on Linux
    71. Re:Who wrote that article? by cgaertner · · Score: 1

      Use -std=c99 instead - this will switch to ANSI C99 (aka ISO 9899) mode
      (which isn't fully implemented yet...)

    72. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      I forwarded the article around to several folks here as a "hint, hint".


      If I were on your team and you forwarded that to me as a "hint, hint", I would never speak to you again. I'd take that article as an insult.
    73. Re:Who wrote that article? by TemporalBeing · · Score: 1
      Sadly, I've seen worse in the real world...something like the following:

      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();
      return;
      }
      return;
      }
      Only, going on for 3, 4, or more block depth levels, and for several hundred lines at a time - with no, or little, error checking, etc. Not fun stuff to maintain - and one of the first things I do is make the code sane to read. Then I can start maintaining it.

      Note: I only added a single return and two braces. The code does the same thing as the parents quoted code.
      --
      Truth is like the sun. You can shut it out for a time, but it ain't goin' away. - Elvis Presley (source: imdb.com)
    74. Re:Who wrote that article? by achacha · · Score: 1

      Counter-counter point, if you have novices writing optimizations then the project is already doomed, else an experienced programmer will be able to write readable optimized code from the start.

    75. Re:Who wrote that article? by Anonymous Coward · · Score: 0

      You should make comments like that when the behavior of the code isn't obvious. For example,

      Here it's a bad comment:
      int x = 5;
      //Increment x by one
      x++;

      ... whereas here it's a GREAT comment:
      class Int;
      //Increment x by one
      x--;

      ...

      class Int {
      int i;
      public:
      Int operator--(int) {
      return Int(i+1);
      }
      Int(int x) {
      i=x;
      }
      }

      Why are the best comments always found in bad code? :(

    76. Re:Who wrote that article? by thePowerOfGrayskull · · Score: 1

      Sure it's a great comment in that context, but the code is so bad that if I saw it in an application I was using, I would immediately find a different vendor/library to use ;)

    77. Re:Who wrote that article? by segra · · Score: 1

      lucky, Microsoft writes some the most widely used exploitable code on the planet :)

  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

    1. Re:Damn by jstretch78 · · Score: 0

      I'm working on a similar one except with chairs instead of *pew pew* lasers.

    2. Re:Damn by Cesa · · Score: 1

      Duke nukem forever, they switched graphics engine yet again.

    3. Re:Damn by VoltageX · · Score: 1

      Duke Nukem Forever.

      --
      "Anonymous could not immediately be reached for further comment." - International Business Times
    4. Re:Damn by Idbar · · Score: 1

      Duh! Take the code on the page and compile it! It looks very well commented by the way!

    5. Re:Damn by eugene+ts+wong · · Score: 1
      Well, the source is open.

      1. Just cut and paste from the article.
      2. Add variables, if-statements, and objects.
      3. Compile.
      4. Rename.


      It's easy. Most of the hard work is already done already.
    6. Re:Damn by CarlHungus · · Score: 0

      Kill Bad Aliens would be my guess but maybe that's a codename. Did TFA mention when it would be released?

    7. Re:Damn by master_p · · Score: 1

      Duke Nukem Forever! running on a 80-core POWER7 architecture! with real-time raytracing!

  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 bluephone · · Score: 1

      I agree. It's the old concept of investment. Investing a little now is worth a lot more later. Investing one more minute now in commenting your code saves hours of puzzling later when you need to edit it.

      --
      jX [ Make everything as simple as possible, but no simpler. - Einstein ]
    2. 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.

    3. Re:The whole article is -1 redundant. by butlerdi · · Score: 1

      appropriate sig

      --
      "If the King's English was good enough for Jesus, it's good enough for me!" -- "Ma" Ferguson, Governor of Texas (circa
    4. 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.

    5. Re:The whole article is -1 redundant. by Anonymous Coward · · Score: 0

      I for one, bend peoples MIND with my SPOON.

    6. Re:The whole article is -1 redundant. by mstahl · · Score: 1

      The whole article is -1 redundant.

      You'd think so, but I think there are enough examples out there to show that there are a lot of people out there writing sub-standard code and thinking there's nothing at all wrong with it. There have been a lot of times when I was tutoring computer science in college where I'd ask a student, "Just what in the hell were you doing here?" and point to some ridiculous incantation in their code.

      In particular I think people ignore that last two when they're in school, because everybody wants to look impressive and figure out the "best" way to approach the problem at hand. What takes maturity and experience to realize, though, is that elegant simplicity will always win above arcane obfuscation.

      I'm not defending bad code here. I'm just saying it happens so often it's hard to really hard to criticize so much.

    7. Re:The whole article is -1 redundant. by hobo+sapiens · · Score: 1

      absolutely. I work for a large corporation, with a huge IT department. You'd be surprised to see how many "well educated" people write horrid code, and for a variety of reasons. Some do it for job security (I say let em support it forever then). Some do it to be "clever". Some do it to "separate the wheat from the chaff" but that's a lot like making jokes about things that have happened in your life that only you'd get and expecting others to laugh. Nobody else knows what you are thinking when you write code.

      On a tangent, one thing that bugged me was that he left proper indentation out of the article.

      --
      blah blah blah
    8. Re:The whole article is -1 redundant. by PinkyDead · · Score: 1

      100% agree. My guess is that the article is +5 redundant.

      Two nasty types of developer exist out there - the complete noob ( which makes up about 80% of them ) who doesn't follow these rules and is hell to support, and the complete elitist to whom the rules are second nature but is oblivious to the fact that complete noobs write code.

      The elitist's response is always "here are the rules, you will follow them - because I say so and I am the best". The noob never learns because the elitist is a muppet with no patience. [Popular line: Those that can do, those that can't teach - ergo teaching is a waste of time]

      And why are there 80% noobs, because they are chargeable - they're shite, but they are still chargeable (PHB is happy). And once the client has paid for the rubbish they write, the client (because he's stupid) will pay for it to be supported by idiots like you and me. Welcome to hell, please wipe your feet.

      --
      Genesis 1:32 And God typed :wq!
    9. Re:The whole article is -1 redundant. by rapidweather · · Score: 1

      Didn't I read somewhere that Bill Gates stopped all of his code writers for nearly a month, so they could learn how to comment their code, so others in the Microsoft organization could make sense of it?

      I try to comment my code to the extreme, since it's mine anyway, and I want the thing to be self-contained, in that a readme is in there. Here is an example you can see.

      I'm not a professionally trained programmer, but I dog it along until it does what I want.

    10. Re:The whole article is -1 redundant. by glitch23 · · Score: 0

      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.

      Support people actually talk to the developers? I didn't know that happened in this universe, or is this support group an anonymous one that meets in the cafeteria on Tuesdays?

      --
      this nation, under God, shall have a new birth of freedom. -- Lincoln, Gettysburg Address
    11. Re:The whole article is -1 redundant. by aslate · · Score: 1
      This is from our "Reasoning about programming" exam (1st Year Computing at Imperial College, top Uni in Europe for CompSci). Granted, this exam is supposed to be about reasoning and logic about programming, but this is a perfect example of how to fuck up code. All indenting, spacing and newlines the same as the exam. The bold parts are in reference to questions set about the program.

      int partition (int [] a, int x) {
      //Pre: none
      //Post: 0<=r<=a.length &
      // (A)i:int(0<=i<r-->a[i]<x & r<=i<a.length-->a[i]>=x)
      int greyStart = 0;
      int bigStart =a.length;
      while (greyStart < bigStart) {// Outer while loop
      // Variant: bigStart-greyStart
      // Invariant: 0<=greyStart<=bigStart<=a.length &
      // (A)i:int(0<=i< greyStart-->a[i]<x &
      // bigStart<=i<a.length-->a[i]>=x)
          while((greyStart<bigStart) && (a[greyStart<x)){
      // First inner loop: <b>See part(d)</b> (***)
      // Variant and Invariant: <b>See part(B)</b>
              greyStart++;}
          while((bigStart>greyStart) && (a[bigStart-1]>=x)) {
      // Variant: bisStart-greyStart
              bigStart--;}
          if (greyStart<bigStart) {
              swap(a, greyStart, bigStart-1);
      //swaps a[greyStart with a[bigStart-1]
              bigStart--; greyStart++;}
          }
      return bigStart;
      }
      And although there is the disclaimer at the top, we found code with similarly huge and utterly useless (or over the top) commenting from our programming lectures. This is at the stage where you're learning how to program, not at the stage where you're meant to learn about how to thoroughly prove programs mathematically.
    12. Re:The whole article is -1 redundant. by Bill+Dog · · Score: 1

      ...a muppet with no patience.

      Then again, things don't go so well when muppets have patience. ;-)

      --
      Attention zealots and haters: 00100 00100
    13. Re:The whole article is -1 redundant. by rah1420 · · Score: 1

      Support people actually talk to the developers?

      Yep. A very high intensity focused deployment, mind you, but within a Fortune 50 company. So it does happen.

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

      And yet...

      Most code out there

      * Isn't well commented
      * Isn't really clearly written
      * Use hard coded values

      So redundant? Only if you think that these things are not important...

  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 Anonymous Coward · · Score: 0

      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.
      Well the guy has been around in the Mac world forever, without about the worst looking games you'll ever see on that platform (even back in the 90s, they were utter garbage.)

      I don't believe he's published anything in years-

      He's probably not the best guy to give advice on coding.
    2. 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.
    3. 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?
    4. Re:That was just terrible... by Dancindan84 · · Score: 0

      Agreed. This is year one CS stuff. If you haven't learned this you shouldn't be coding in the first place.

      What's next, a ground breaking article on how QA testing is important?

      --
      "Always forgive your enemies; nothing annoys them so much." - Oscar Wilde
    5. 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.
    6. Re:That was just terrible... by FortKnox · · Score: 1

      I accept most of your arguments, except for TDD, which I have used to success...

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

      TDD (for me, at least) helps with the design. You can't just start writing test cases, it forces you to 'stub out' your entire design. In this process, I can immediately start seeing problems and reworking it. Its only after I have a good design that I start writing test cases. And refactoring of the design may kill some test cases, but it keeps a good portion alive, which can be almost a 'regression' test of the refactored code, so it all still passes the tests that are still valid...

      --
      Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
    7. Re:That was just terrible... by Anonymous Coward · · Score: 0

      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. That style of programming is common in Smalltalk. I think it works well when you get used to it: the text reads like simple prose, just method invocation after method invocation. Each method is small enough that you can understand it directly, and it has an expressive name. You don't want hundreds of methods in a single class, of course; that's a sign that you need a better class hierarchy.

      It helps that in a Smalltalk environment, you commonly have

      1. Simple uncluttered syntax involving only composition of methods
      2. Expressive descriptors ('view plotX:10 Y:10 color:#RED' instead of 'view.plot(10,20,RED)')
      3. A refactoring multipane code browser to easily browse and reorganize your code (not that you can't get that for other languages)

      "Self-documenting code" is a myth, but this style comes closer than many others I've seen, when done right. The C3 project had an average method length of 3.8 lines ...
    8. Re:That was just terrible... by DigitalCrackPipe · · Score: 1

      I'd suggest that commenting the function calls may also be needed at times, such as when calling a legacy function that has tricky (or just plain inappropriate) calling conventions or side effects. I see plenty of places where a comment is useful for 2-3 lines of code, and it would not be appropriate to make a function out of all of those instances.

    9. Re:That was just terrible... by seaturnip · · Score: 1

      Not to mention, the "never optimize prematurely" advice can be very dangerous if applied blindly. By all means wait until later to optimize inner loops, but don't commit yourself to an architectural decision that implies performance can never be improved. You'd think a game developer of all people would understand this.

    10. Re:That was just terrible... by Ambitwistor · · Score: 1

      CS graduates don't appear to be the intended audience. TFA says, "But there are many who, like me, stumbled into programming in an unexpected or unusual way and never had anyone drill this stuff into them. These things are basic to many but, to others, they are invaluable techniques that nobody has told them. So, to those who don't want to make a mess, this is for you."

    11. Re:That was just terrible... by Anonymous Coward · · Score: 0

      Make sure to pick up the phone the next time an automated refactoring tool gives you a call.

    12. Re:That was just terrible... by Dancindan84 · · Score: 1

      That's great, but in that case I don't think that warrants it being an article in the developers section of slashdot. When I come to this section I expect new programming or systems analysis techniques, ground breaking news about various languages or development companies... not programming basics. What's next? An article about using conditional statements?

      --
      "Always forgive your enemies; nothing annoys them so much." - Oscar Wilde
    13. 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
    14. Re:That was just terrible... by cliffski · · Score: 1

      Or in the case of games (what the author writes, and what I write to), stuff that the user may want to fiddle with. I've been using data driven code for a while, but after people were so keen to mod my last 2 games, my new one (www.rocklegendgame.com) had pretty much every notable variable placed in an external text file (a fully commented one called config.txt in the data dir) with the express purpose of letting the techy gamer play with it. Theres the usual discliamer that says the game has been balanced for the default variables, but if any piece of the gameplay code upsets you, all the numbers are there for you to fiddle with.
      Plus there are other benefits, it made playbalancing quicker and easier, with no recompiles, or worry about a type corrupting some code. It means I can do easier or harder builds for different publishers without recompiling the exe, and lets me toggle the game into certain cheat configs to check bugs without recompiling.
      External data files containing your config FTW.

      --
      DRM-free indie games for the PC and Mac: Positech Games
    15. 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

    16. Re:That was just terrible... by hobo+sapiens · · Score: 1

      well, depends on how you define "optimize".

      An experienced programmer will know what to do and what not to do inside a loop. You write optimal code, but you don't do "special" stuff unless you need to.

      As a real life (for me) example of "special stuff", I have an javascript program that has a loop in it to build html elements based on data obtained from a JSON object. I have a function, prototype's $() function, if you know what that is. If you don't, it's a function that you pass an element's id to and it returns a fully qualified object var. Anyway, this function checks for legacy DOMs, accepts an array of element IDs, etc, and therefore does more than a simple document.getElementById() does. So, since I use my $ function everywhere in the program, I use it in the loop, right? Most people probably would, knowing that it's less efficient than getElementById, but for the sake of consistency, they'd do it. Consistency often = readability. But in some cases a large dataset could be returned, so you have to optimize but dropping the $ function and doing a getElementById so you don't call $ 1000 times. But you don't prematurely optimize, blindly using getElementById everywhere you think a problem might exist. That decreases readability and consistency.

      Bottom line is, you write the best code you can, and then go back and start trimming things, consolidating statements, etc, only when you need to. Otherwise, you become one of those people who write a line of code that does like five things (like you can readily in languages like C, javascript, java, etc), which can be very confusing to read. I used to think that statement "Premature optimization is the root of all evil" was a bunch of crap. Then I kept living and coding and learned otherwise.

      --
      blah blah blah
    17. Re:That was just terrible... by PitaBred · · Score: 1

      You don't know any developers you could send this to? I know of at least 2 or 3 within earshot of me that could use reading it. Even if you didn't need the info directly yourself, don't you wish you had access to it to show someone sometimes?

    18. Re:That was just terrible... by dkf · · Score: 1

      ... unless a constant is going to change frequently ...
      A constant that changes frequently is called a variable. HTH!
      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    19. 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.
    20. Re:That was just terrible... by dkf · · Score: 1

      Test-driven development is OK, but it is very hard to do right. The problem is, writing a good set of tests that specify the functionality you require is actually pretty much identical to formally specifying the semantics of the code required to solve the problem. That's very difficult. (If you can do it, it's a really good plan.)

      Myself, when doing development I tend to write black-box tests to show the correctness of the core of what I'm doing before writing code, and then write white-box tests afterwards to show the correctness of any tricky cases I discover during implementation (resource cleanup can get complex, and it can take a lot of thought to figure out a good way of testing threaded code for races). When doing maintenance, I don't touch code until the bug is characterized by at least one reproducible test case.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    21. Re:That was just terrible... by dkf · · Score: 0, Troll

      Breaking all of those [5 or 6 line segments of functions] into independent functions leaves you with hundreds of 5 or 6 line functions, which is even harder to understand how they interact.
      This is the essence of Ravioli Code. Some people claim that it is good style. Some people are dangerous idiots.
      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    22. 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.
    23. Re:That was just terrible... by seaturnip · · Score: 1

      Certainly, but there is nothing architectural about the optimization you described.

      What I'm talking about is things like, say there is some locality property in elements of a large dataset that would make it more efficient to subdivide them into groups. At the beginning of your project you just put them all in a huge unified pool, because that is simpler and after all one shouldn't optimize prematurely. But then later on you find it is incredibly difficult to make that optimization, because all sorts of code written later depends explicitly or subtly on the data being in a big pool. It would've been better to consider the optimization (or at least the architectural aspect of it) at the design stage.

    24. Re:That was just terrible... by ufnoise · · Score: 1

      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.


      Actually, if you worried about that. Create an everything.cc and compile it separately. Then use extern in everything.h.

      in everything.h:

      extern const int num_players;

      in everything.cc:

      const int num_players = 5;

      If you worried about performance in optimized builds, have a macro define trigger everything.h to include everything.cc.

      #ifdef NDEBUG
      #include "everything.cc"
      #endif

      And for the love of god, use namespaces to encapsulate global variables.

    25. Re:That was just terrible... by hobo+sapiens · · Score: 1

      Good design and optimization are two different things.

      Good design is taking things into account at the architectural level like what you described.

      Optimization, as I am defining it, is typically never a matter of totally redesigning something. Optimization is making many small tweaks that add up. Inside a loop, can you possibly consolidate two or more statements into one? Could you use lighter functions / logical constructs? Could you declare fewer variables and just re-use what you have? Optimization is cutting the fat; fat that you might want to leave if possible. In all of the above cases, you'll get more optimal code maybe, but it's going to cost you some clarity and readability.

      As my first C prof said, readability and performance are at odds. You've gotta find the balance.

      --
      blah blah blah
    26. Re:That was just terrible... by TheOriginalRevdoc · · Score: 1

      I think it would be great if professional, experienced programmers wrote commented, clear code. As it stands, most of them *don't*. Seeing 1,000 line PL/SQL packages with zero comments, random indenting, single-letter variable names and hard-coded constants is an almost daily experience for me.

      As for keeping constants in a database table or a file: well, yeah, sure, but how are you going to look them up? You'll need some kind of human-readable identifier value to find them in the table. I guess you'll be using a constant for that.

    27. Re:That was just terrible... by AuMatar · · Score: 1

      C also has enums, and has for some time. The const keyword was added in C99. As was inline. So the only reason to use #define these days is for deep preprocessor magic, to which the usual reaction should be "don't".

      --
      I still have more fans than freaks. WTF is wrong with you people?
    28. Re:That was just terrible... by EdelFactor19 · · Score: 1

      if everyone created functions for any piece of code so complex it required a comment, you'd spend more time writing func_proto's and functions calls (and then later making context switches) then you would doing anything else.

      Plus it just creates more spaghetti for you to go through later..
      If something needs a comment, give it one. I'd break off a seperate function if the chunk is likely to be resusable elsewhere, is performing a distinct task that is seperate from what the current scoped function is doing. This method is also extremely impractical when you are accessing a large amount of different variables/objects. Things get ugly when you start to pass in 8+ arguments to a function. Yes its often done, just look at openGL, and yes it has a reason. But in general it isnt fun because you constantly have to look back and forth to remember which arg was which and to make sure they were all passed properly. Especially if you are going to be constructing, or malloc'ing any new memory.

      Plus if you are in C there no methods... methods are functions anyhow. And wouldn't commenting a function involve a comment here or there on some of the code in its body?

      comments are Especially important when you are doing things in a more optimal way to explain what the heck you are doing and why. Because eventually there will be some optimization, and even if there isn't you want to reduce the work that someone new looking at your code has to go through.

      A parallel idea is to write skeleton code first and implement details later. Just create a bunch of prototypes and your general outline of whats happening everywhere, and then go back and start making each function in the chain work. In the process you will have to create more outlines (as you create the need for more funcs) and you will also have a pretty understandable easy to explain structure.

      --
      "Jazz isn't dead, it just smells funny" ~Frank Zappa
      EdelFactor
    29. Re:That was just terrible... by seaturnip · · Score: 1

      Well okay, but I think most people understand optimization to mean "making it faster/smaller". You are just restricting the term to mean exclusively low-level optimization.

    30. Re:That was just terrible... by Anonymous Coward · · Score: 0

      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.

      Making sweeping generalizations - bad.

      It leads to a lot of wasted time, completely rewritten test suites, and throw away work.

      Whenever I do it, it leads to less wasted time than otherwise, test suites that match exactly the functionality, and which can be run in production.

      Thinking about testing early is useful, it may cause you to think about corner cases.

      And *writing* tests for these corner cases *will* cause you to write code to handle them. If thinking about something is good, having working code for it is even better.

      But writing them first causes 2 problems- you end up writing the code to solve the tests (rather than solving the problem)

      If you write the tests to demonstrate the problem, then your code to pass the tests will solve your problem. Writing tests firsts keeps you focused on delivering working code. I've never seen the problem you claim.

      and/or you end up throwing away half the test suite in the middle when you refactor the design.

      And if you're throwing away half the test suite, that's good evidence that what you're doing is not refactoring. Refactoring is "any change to a computer program which improves its readability or simplifies its structure without changing its results". Unit tests test results, so if you remove half your unit tests, you're changing the results pretty significantly, and it's not refactoring. If it's truly refactoring, you wouldn't want to do it without unit tests, because the unit tests give you confidence that you're not actually changing the results.

      Test-driven development and refactoring can be done really well. I'm not sure if you're arguing against that, or just arguing against the words "test-driven development" and "refactoring" without understanding what they mean.

    31. 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'!"
    32. Re:That was just terrible... by HaMMeReD3 · · Score: 1

      As per your #3

      I agree that you don't want to refactor all your code into functions just for the hell of it, but I also very strongly believe in no code duplication. If you have 2 blocks that do almost the same thing they should be consolidated 99% of the time into a single function.

      Also as mentioned before, comments are a maintenance liability, sure they might save you 1 hour one time, but an out of date comment might waste 2 hours sending you in the complete wrong direction. IMHO, if a programmer needs comments, either the system and code is crappy, or the programmer is incompetent. Code should be written as if it were one big comment, clear and concise, easy on the eyes, with layers of abstraction that make even the most complex system easy to understand at one of it's levels.

    33. Re:That was just terrible... by AuMatar · · Score: 1

      And *writing* tests for these corner cases *will* cause you to write code to handle them. If thinking about something is good, having working code for it is even better.


      Sure- at the end. At the beginning, its wasted effort. Your code will be refactored. You will change inputs and outputs of functions. You will find corner cases in coding that you won't in design. Thinking about the test cases gives you insight. Writing them first just means you're going to have to rewrite them 3-4 times during the coding- a lot of throw away work and lost productivity due to switching tasks. While unit tests are a good thing, writing them first is a loss of productivity.

      If you write the tests to demonstrate the problem, then your code to pass the tests will solve your problem. Writing tests firsts keeps you focused on delivering working code. I've never seen the problem you claim.


      The problem is that you then write code to pass tests, not to solve the problem. You will always miss some wrinkle in the problem on any task of real complexity. You'll have to go back and refactor/rearchitect your code to fix it. If you writing to solve a set of test cases, you end up with code that works perfectly for those tests, and only those tests.

      And god forbid he test itself be wrong. Half the time it is (tests are code too, and have bugs). Trying to get half the "but it passed the test" TDD advocates to admit its a possibility is like pulling teeth.
      --
      I still have more fans than freaks. WTF is wrong with you people?
    34. Re:That was just terrible... by AuMatar · · Score: 1

      Well, no code duplication is unrealistic, but very low code duplication I agree with.

      Comments are *NOT* a maintenance liability. I'd rather have a wrong comment that tells me what the code was trying to do at one point, then no comment at all. Hell, I almost like it when the comments are wrong- 99% of the time thats the point where the problem is. Not that it really matters- comments don't get wrong, unless you have shitty programmers. Half a programmers job is to keep the documentation up to date. That includes comments. If you don't fix the comments with your code, you're doing sloppy work.

      As for code being written as 1 big comment- the idea that self-documenting code exists is the biggest myth in software today. The fact is, people are different. People think differently. What you think is an obvious name, I may not. What you think is a reasonable level of abstraction, I may find to be too abstract, or not abstract enough. Or abstracted in the wrong way. And vice versa, of course. Self documenting code is self documenting in only one situation- to the original author, 10 minutes after he wrote it. After that, you need comments and documentiation. The guy who works on it next won't find your intuitively obvious code obvious at all.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    35. Re:That was just terrible... by epine · · Score: 1

      On the contrary, there are absolutely good places to abuse the C preprocessor. It needs to be well judged, and documented to a far higher standard than regular code. I used preprocessor magic extensively in coding interrupt handlers for a microcontroller project and I'm pretty sure I used some more to code the platform specific hooks for the C library. If the task is duplicitous, fragile, prone to error, or especially time critical there is no reason at all not to employ the preprocessor with a little discipline.

    36. Re:That was just terrible... by Anonymous Coward · · Score: 0

      Writing them first just means you're going to have to rewrite them 3-4 times during the coding- a lot of throw away work and lost productivity due to switching tasks. While unit tests are a good thing, writing them first is a loss of productivity.

      You keep saying this, as if repeating it makes it more true. I've never found this to be the case, though.

      The problem is that you then write code to pass tests, not to solve the problem. You will always miss some wrinkle in the problem on any task of real complexity. You'll have to go back and refactor/rearchitect your code to fix it. If you writing to solve a set of test cases, you end up with code that works perfectly for those tests, and only those tests.

      Again, you're just repeating yourself.

      I'm working on a program with almost 200,000 lines of (HLL) code right now, and I don't see why TDD wouldn't work well if we had to scale up by an order of magnitude or so. Maybe in the multi-million-LOC range you hit "real complexity" and need to come up with a different approach, but there aren't that many programs in the world with that level of complexity. The vast majority of projects have under a half million LOC, and for us, TDD works fine.

      And god forbid he test itself be wrong. Half the time it is (tests are code too, and have bugs). Trying to get half the "but it passed the test" TDD advocates to admit its a possibility is like pulling teeth.

      Sure, it happens. But far less than half the time, because unit tests are, by design, really simple. If your "TDD advocates" think unit tests trump common sense, then your problem is really with these moronic programmers you have to work with, not TDD itself. No respectable programmer (TDD advocate or otherwise) would claim that unit tests are perfect.

    37. Re:That was just terrible... by HaMMeReD3 · · Score: 1

      I do have documentation on my code, just not in the code.

      UML Docs, etc that explain the architecture and how everything works together, anytime we add someone new to the team we make them update it. People learn that first and then I don't need to spend as much time explaining my mindset and abstractions when doing design.

      My code is 99% comment free though, all 15,000+ lines of it, and so far I haven't had problems bringing someone up to speed on it. The only place I'll expect comments is when a section is complex to the point where it is necessary.

      Actually, if I had to give 1 thing that would help you in the long run when coding it would be design. A proper initial design pays off more then any other thing I could possibly do, it definitely has 100x the worth for long term code maintenance then comments do. A crappy system isn't going to be saved on the quality of it's comments though.

    38. Re:That was just terrible... by roman_mir · · Score: 1

      I believe the only thing that REQUIRES comments are classes and methods. Not pieces of code... - nothing 'requires' comments, not even classes or methods, but supplying a business reason for a piece of code ('business' being anything from a parallel video processing algorithm description to an order management system XML usage quirk) is a GOOD IDEA.

    39. Re:That was just terrible... by Anonymous Coward · · Score: 0

      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.


      You're right. Everything should just be in main()
    40. Re:That was just terrible... by Anonymous Coward · · Score: 0

      Hiding complexity is the whole fricken point of software engineering.

    41. Re:That was just terrible... by Anonymous Coward · · Score: 0

      OK, test your code, sure, but that's not really so much about writing code, but more of, well, something completely different.

      In particular, testing the little things is often counterproductive. Many methods have no real relevance to the finished product, and they're hard to test. Break it down into reasonable sized subsystems, perhaps one comprehensive unit test for every few thousand lines of code. In particular, test the actual APIs you'll expose, and any substantial subsystems. If you have really comprehensive unit tests for your APIs, then it's unlikely that any significant bugs can slip by. Checking function inputs pretty regularly will also catch the majority of foolish errors.

      Your #3 is good where it's viable. In particular, lots of nested loop style formulas don't work well like this, you spend so much effort passing and packing parameters and return values that it makes the code less clear.

      How about some simple ones that nobody ever does. Here's my top 7.

      1) One statement per line. Especially true in Java where the JVM will tell you which line is the problem in the case of an exception. There is no prize for cramming 100 statements onto one line, it's not really any shorter of a program. In addition, if you stored this stuff in variables, you can look at the intermediate values in the debugger, set breakpoints at any point of the calculation, step into any part of the calculation (easily), and your source control system will show you what is actually changing, rather than just pointing out that the huge blob of code that wraps 12 times is different, gee, thanks. Even better, if you give your variables reasonable names, then the purpose of the code will generally be pretty clear, as each intermediate value will be well labeled. This is one of the cardinal sins of programming, if you put more than 3-4 operations (array dereference, function call, arithmetic, etc...) on one line, you're a bad programmer, end of story. This is by a huge margin the single best thing you can do to improve your code.

      2) If it's final/const, label it as final/const. This goes for methods, classes, members, variables, parameters, whatever. In Java, final methods will save you lots of time looking up where the actual code is (your IDE will go right to it), and it'll prevent fools from breaking a piece of code that is not simple. If you're not making some huge library to be used by everyone on the planet, then you can always un-finalize what you don't need to be final. Also, if you implement Comparable, then you had better make a final equals method that delegates to compareTo(), after some relevant checks of course.

      3) Make immutable stuff. It's only a matter of time before that mutable object is modified by some yahoo. Also, you'll spend a huge amount of time and effort copying/cloning/unaltering this object if it's not immutable. Nuff said. The getter/setter pattern is (in 99% of cases) a HORRIBLE antipattern. Classes should generally have actual code, and they should generally be immutable unless there's a really good reason for them to change. The biggest hole in this is serialization, where you may need to have lots of members that are really (effectively) final, but marked as non-final because you need to fix them after serialization.

      4) NaN is there for a reason. Check for it, early and often. If you're returning a dummy value that doesn't make sense (function call to uninitialized system, don't want to throw an exception), return NaN. This does happen, even in good code, just make sure that this can't be mistaken for an actual result (don't return 1.0, or 0.0, or whatever).

      5) Throw descriptive exceptions. Especially, always check all parameters in constructors, as often a null here will not be caught (nothing dereferences it in the constructor), and you'll get an exception later on that will be hard to track down. Even if you have a variable that is dereferenced, an explicit null check will tell you exactly what the problem is, even if the code has changed and the line n

    42. Re:That was just terrible... by AuMatar · · Score: 1

      You keep saying this, as if repeating it makes it more true. I've never found this to be the case, though.


      Because I have found it to be the case. I've seen TDD used in multiple projects. I have never seen one of these where the entire test suite wasn't either thrown out, or rewritten to the point where its almost equivalent to throwing it out, at least 3 times. At least not on a project of more than 10K LOC. At this point to get me to use TDD anymore a manager would have to say use it or you're fired. Its just a huge productivity loss at best, counterproductive in the average case.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    43. Re:That was just terrible... by Cederic · · Score: 1


      I've found the difference primarily lies between whether you're writing academic code that you have the time to get right, and for which specifications never change, or whether you're writing code in the real world, where the project is already late (before it's started - every fucking time - don't look at me, look at the marketing department) and where the specifications never change more than forty times a day. Most days.

      I'm not disagreeing with you; pragmatically I know which development approach is less risky overall in the environments I work in.

    44. Re:That was just terrible... by cloudmaster · · Score: 1

      The funny thing about that long post is that it totally misses the point. The article is about good coding practices, not good C++ practices. The specific point is to use named values instead of relatively meaningless numbers, and using #define in the example is a whole lot clearer to people who aren't necessarily C++ developers.

    45. Re:That was just terrible... by gabrieltss · · Score: 1

      I think more programmers SHOULD read this article. I work in Java at work and there are individuals WITH CS degrees writing crap like this:

      public String foo(String bar) {
              int foo = 0;
            String foobar = null;
              while(foo

      And yes this is VERY close to an ACTUAL method. Some of their stuff is so shotty it takes me days to plow through the application trying to figure out what the hell they were doing as I have to now go throug and clean up after their shitty mess and fix the poor performing badly written application - and no they are written by born in the U.S.A person(s)!

      The article may be "primitive" in it's presentation and might be more geared towards new CS students, but there are A LOT of programmers that have been out of College for a while and still code like SHIT! I think they are the ones that -really- need to read this article over and over until it's drilled into their heads.

      --
      The Truth is a Virus!!!
    46. Re:That was just terrible... by Anonymous Coward · · Score: 0

      Q. What's the difference between code commenting and masturbation?
      A. Everybody talks about commenting but nobody does it, whereas nobody talks about masturbation and everybody does it.

    47. Re:That was just terrible... by josu · · Score: 1

      One benefit of having many small functions is that the scope/flow of data is clearer. Usually larger functions have more local variables, some of which are used only a few times. You end up with variable scopes that are longer than necessary, and possibly with variable uses that are far from their definitions. Break your function into smaller pieces, and their parameters will describe the way your data moves around.

    48. Re:That was just terrible... by Anonymous Coward · · Score: 0

      Frequently the correct thing to do is not break it into a function and just write a 1 line comment.

      int a = 1; // Comments should be used when you don't know what's actually going on
      int b = 2; // Using comments when it's not necessary is stupid
      int c = a + b; // It's called a fucking LANGUAGE for a REASON

      Comments should be used when code is complex or convoluted to the point of being beyond intuitiveness. Otherwise, code is written in a LANGUAGE and should thus be readable to the reader. If they can't read it, and it's relatively obvious code, they don't know the language.

      On the flip side, commenting the prototypes of libraries in their header files is necessary, as a user of a library should not be required to "read" the code of the function to know what it does. The above statements are commentary on commenting within the code of the functions/main body of work.
    49. Re:That was just terrible... by Abcd1234 · · Score: 1

      I'll go you one better. Use specification driven development.

      Yeah. Now all you need is a specification. That should be easy enough to get, right?

    50. Re:That was just terrible... by Coryoth · · Score: 1

      Hw do you write unit tests? You know those are a specification right?

    51. Re:That was just terrible... by swillden · · Score: 1

      The funny thing about that long post is that it totally misses the point. The article is about good coding practices, not good C++ practices. The specific point is to use named values instead of relatively meaningless numbers, and using #define in the example is a whole lot clearer to people who aren't necessarily C++ developers.

      All of the examples were in C++. If the author wanted to make it generic, he should have said "define constant values", rather than "use a lot of #defines". And I certainly wasn't suggesting that the author should have gone into Barton and Nackman's techniques, that was simply an interesting (albeit long) aside.

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

      Writing unit tests, which can be done as code is being developed, is *drastically* different from writing all unit tests ahead of time before development has even begun.

      In short, it's a stupid question.

    53. Re:That was just terrible... by An+Onerous+Coward · · Score: 1

      I disagree about the config file. If you know you're going to want something hard-coded when you ship, you might still want to be able to tweak it without recompiling, or have separate config files for development, testing, and production. Hell, you might even decide to leave some of the options for power users to muck about with. Config files add a great deal of flexibility to your program for very little overhead.

      As for TDD, I would argue that the tests you write ought to completely, rigorously embody the problem you want to solve, so saying that you end up writing to pass the tests rather than to solve the problem may be misleading.

      --

      You want the truthiness? You can't handle the truthiness!

    54. Re:That was just terrible... by Coryoth · · Score: 1

      Because contracts, and unit tests, as a specification, can't be changed as code is being developed? I'm not suggesting big design up front, I'm suggesting you make sure you are hammering out your spec at least at the same time as you're hammering out your code, rather than retroactively trying to build some test framework after the fact. The sooner bugs are found the cheaper and easier they are to fix.

    55. Re:That was just terrible... by ChrisMaple · · Score: 1
      The idea of "no code duplication" has important limits. Function calls have overhead, and in some cases that overhead can cause disastrous speed penalties.

      Because the higher level languages I'm familiar with don't allow functions with multiple entry points (without extraordinary grief), many things that could benefit from consolidation into a single function can't be consolidated.

      --
      Contribute to civilization: ari.aynrand.org/donate
    56. Re:That was just terrible... by ChrisMaple · · Score: 1

      It's often the case that the description of variables is hundreds of lines away from the code that uses the variables. Size and signedness, initial values, scaling factors, etc. can easily be unclear where a variable is being used, and can make a world of difference in what a line of code does. A brief comment can clarify matters withhout having to search back for the definitions or open multiple windows. This is particularly true when unions, structures, bit fields, and shifting are involved.

      --
      Contribute to civilization: ari.aynrand.org/donate
    57. Re:That was just terrible... by Abcd1234 · · Score: 1

      I'm not suggesting big design up front

      Then you're not talking about TDD or an subvariant thereof. TDD requires you write your unit tests before writing a single line of code. That, by definition, is "big design up front". Worse, you end up having to update and maintain a massive codebase of tests, while you're refactoring your design to take into account new requirements.

      What you're describing is just plain old unit test practices. ie, writing unit tests as you're developing your code. But that ain't TDD.

    58. Re:That was just terrible... by Coryoth · · Score: 1

      The suggestion that TDD is somehow not Agile seems a little bizarre to me. TDD doesn't suggest you sit out and write every unit test for the entire software system first, it simply suggests you write tests as you get the requirements, and then code to the tests. All I am suggesting is writing tests and contracts as soon as you can, and coding to those. I'm not in any wasy suggesting you fix them in stone as soon as you write them. By all means change the contracts and tests as the spec and requirements get refined. Those changes will, in turn, necessitate changes in code.

    59. Re:That was just terrible... by djcondor · · Score: 1

      "This looks like it was written for (and BY) freshmen CS majors."

      Please note, the top line of the article reads "Level: Introductory"

      Now, kindly climb back up onto your self-constructed pedestal and leave us mere mortals alone.

      --
      Now with more sodium!!
    60. Re:That was just terrible... by Thunderbear · · Score: 1

      I agree fully with that, even if I mainly use TDD for smaller library functions. If you are in the middle of some existing code where you need to add new functionality which will be hard to test and where you just want something that works, TDD is perfect for getting your mind clear on the matter before you actually code anything, and the code tends to be clearer since you don't focus on all kinds of special cases unless you are going to need it. The test cases show exactly how the code is intended to work.

      My suggestion is to the original poster that he tries this with a good unit testing package for his favorite language, and see if it improves the design.

      An issue that is also frequently overlooked is that the test code is the best documentation on how to use the tested code. It shows usage, special cases and is guaranteed to be correct.

      --

      --
      Thorbjørn Ravn Andersen "...and...Tubular Bells!"
    61. Re:That was just terrible... by cloudmaster · · Score: 1

      Quoting the text of that section:

      Just about every time you define a constant number, you should strongly consider defining it in one central place.

      I guess if you only read the headings, you'd miss that. There's also a for loop in there which sets and increments lowercase i, but tests uppercase I to determine if it should exit. Does that mean that I should copy that verbatim as well, instead of just getting the point and using my own judgment as to what feature of my language of choice best implements the tip?

      PS - I agree with the use of enums, they're neat. Harder to read for a novice, but still neat.

  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. What about legacy code? by peopleAreTheProblem · · Score: 1

    The article has some good pointers. But what if you not the one who wrote the code (Developer hired to finish another developers work)? What can I do to minimize the nightmare of work required to deal with tightly coupled, non documented, and hard to read code? It would be nice if there was an article that could help with that.

    1. Re:What about legacy code? by Applekid · · Score: 1

      I throw in comments as I see them. If I just spent hours tracing dragon code, I'm sure as hell going to put a comment in there so I don't have to do it again.

      --
      More Twoson than Cupertino
    2. Re:What about legacy code? by SomeWhiteGuy · · Score: 1

      I'm having to deal with that right now. There is no real way to deal with it. Comment what you put in and move on. The legacy will just have to live on. We currently have a variable that is never used but declared in our main application called ken_is_a_jackass. This boolean is set to true but never mentioned again in code. Good and bad comments/code will stay with a system long after you're gone. Ken has apparently been a jackass for over 12 years and nobody seems to want to get rid of it.

    3. Re:What about legacy code? by CastrTroy · · Score: 1

      Before add any new features or fix old bugs go through the code and comment everything you can. It may not be feasible for a large project, but at least go through and comment the stuff you're going to work on before you change anything. Don't be afraid to write down comments stating that you have no idea what's going on, and some kind of easily searchable tag so that you can go back later to figure out what's going on. Also, don't be afraid to rewrite large sections of code if you really think it will make it a lot cleaner and easier to understand. Oh, and always use source control so you can go back and see what the original code was doing.

      --

      Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
    4. Re:What about legacy code? by Anonymous Coward · · Score: 0

      Let's rephrase that:

      "Also, don't be afraid to rewrite large sections of code if you really completely understand what it does and don't mind introducing new bugs."

      Yup, that's more like it.

      -- J

    5. Re:What about legacy code? by CastrTroy · · Score: 1

      While it's not a good idea to go around changing everything all the time, it might be a good idea to rewrite certain sections if you have to do any extensive work on them. You have to ask yourself, am I going to create more bugs by rewriting the code, or by trying to change the code that I don't understand. And since bugs will be there anyway, is it going to be easier to fix the bugs that do show up when they are in well managed code than in the spaghetti code you inherited from someone else. And when you fix the bugs you introduced into the spaghetti code, will you generate even more bugs. It's a decision you have to reach for yourself. But if the code is really terrible, and you will have to be making changes to it for some time, it may be easier to rewrite the code, and fix the resulting bugs, then deal with the spaghetti code forever.

      --

      Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
  7. 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.

    1. Re:Summary: Beginners need tips too. by P3NIS_CLEAVER · · Score: 1

      For the rest of us I recommend "The Pragmatic Programmer" by Andrew Hunt and David Thomas.

      --
      Please sign petition to restore sanity to our banking system!!!

      http://financialpetition.org/
    2. Re:Summary: Beginners need tips too. by dkf · · Score: 1
      For more expert programmers, there are fewer tips.
      1. Name your functions sensibly and consistently
      2. Make sure every function has coherent semantics
      3. Avoid premature optimization
      4. Clarity is better than cleverness
      Funnily enough, those last two were on the previous list too. But then I've found that even experts tend to struggle with their dictums. ;-)
      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    3. Re:Summary: Beginners need tips too. by jafac · · Score: 1

      I think he spent too much time explaining how NOT to comment.

      I wouldn't say the goal of commenting is to "write smart comments".
      The goal should be "think about your audience" (which should be the goal of ANY writer; including a coder).

      Your audience, is you, 6 months to a year from now, at 2 in the morning, trying to fix a bug, and get it built to make your demo work so your team doesn't get canned because your boss over-promised.

      I would say - for some of the "stupid" comments he writes about - sure, avoid those, but that's not important. The REAL important thing to comment is; ANY weird behavior, any strange environmental tweak you had to make to get a piece of code to work, any odd limits that you didn't forsee, but you hit in testing, any observed issues that maybe weren't reproducible that you suspect had something to do with that block. You'll come back 6 months to a year (or more) down the road, and you'll thank yourself - because it's these little obscure bits you won't remember. There's nothing more frustrating than plowing through a problem, and at arriving at the solution, realizing, that you had gone through all that before, a few months earlier, and - maybe the fix didn't get checked in or merged, or maybe you didn't complete it, but you got pulled in another direction by someone else's "emergency" or something.

      THIS is what comments are for.

      I tell you - I'd rather sort through 1000 lines of inane comments and code, than 200 lines of code written by someone who thought he was clever (and maybe he was) - and decided that since I wasn't as clever, I didn't "deserve" to understand what he had written.

      In summary:
      The intended audience of code is: the compiler.
      The intended audience of commentary is: other developers on your team; and your future self.

      --

      These are my friends, See how they glisten. See this one shine, how he smiles in the light.
    4. Re:Summary: Beginners need tips too. by danlock4 · · Score: 1
      >> The author may not be a beginning programmer, but it appears that he might be a beginning writer on programming.
      On Spiderweb Software's News page it says this:

      5-30-2007: IBM, in its infinite wisdom, asked Jeff Vogel to write an article about programming practices. The result is here. You might think his ideas are stupid, but that is all right. It doesn't matter that he was stupid. What does matter is that he was paid.
      Remember, Jeff Vogel is the author of the article referenced by TFA. Please note especially the last sentence in his News entry.

      --
      To .sig or not to .sig, that is the question.
  8. In Soviet Russia by quarrelinastraw · · Score: 2, Funny

    In Soviet Russia, code destroys YOU!

  9. 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 Palmyst · · Score: 1

      Good point. In my very long experience in this industry, the star programmers cobble something together as fast as possible without worrying about maintenance or documentation. What documentation there is is just the minimum that is needed for various members of the team to work together to make release 1.0, not something that will help future maintainers of the code very much. After release 1.0, they cash in their chips and move on to The New New Thing (yes, I am specifically referring to certain people in that book), and leave the system to be maintained by someone else with less cachet.

    3. Re:Expected Value by pclminion · · Score: 1

      This is a pretty good point. I comment heavily not only because it's policy but because the kind of code we write is by nature pretty obscure and it's hard to find people who are already heavily versed in the particular field. Typically I'll write comments before I write the code that does what the comment says. And if I begin to modify a piece of code, the first thing I do is insert the letters "XXX" at the beginning of the appropriate comment. Once my changes are stabilized, I go back, update the comment, and remove the XXX. This makes it trivial to find comments that have gotten out of sync with reality -- just search for XXX.

      When I code for myself I never write comments. If the code needs comments it means it isn't clear enough. I've come back to personal projects that have languished for years and had no problem getting back into them. Picking good names for things and using appropriate structures goes a long way.

    4. Re:Expected Value by tb()ne · · Score: 1

      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.

      The problem is that attitude only works in certain types of environments, such as one where every programmer is working on their own one-person project. Based on what you wrote, I guess it would have actually been to your benefit to intentionally make your code harder for others to maintain.

      When I was a programmer, the people who did the least documentation were often fastest, usually the sloppiest, and often the only folks who could approach certain parts of code. So they got stuck maintaining those parts of code instead of moving on to better projects. They were also less likely to be selected for larger projects that required collaborative development because neither the project leads nor the other programmers wanted to work with them. Some of them eventually learned to play nice with the other programmers. The ones that didn't were encouraged to pursue other career options.

    5. Re:Expected Value by Anonymous+Brave+Guy · · Score: 1

      In my very long experience in this industry, the star programmers cobble something together as fast as possible without worrying about maintenance or documentation.

      In my experience, what real star programmers cobble together is usually remarkably self-documenting. The best overall developers — the people you'd actually want to hire — are a combination of "star programmer" and conscientious worker who at least writes up the basic reference documentation for others less skilled and/or experienced than them who will come later.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    6. 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.

    7. Re:Expected Value by ebbe11 · · Score: 1

      Almost every time I commit to commenting more, I can't find things to comment that aren't obvious in the code. What is obvious now usually isn't when you have to make a change in the code six months later. And yes, that is personal experience, gathered more frequently that I like to admit over the last 26 years I have spent writing code for a living.

      (Almost) any programmer can write code that works. The hard part is writing code that keeps working.
      --

      My opinion? See above.
  10. 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 EvanED · · Score: 1
      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.

      With the caveat that you're not working in C. Unfortunately, even in C99 consts are broken in that they can't be used as array bounds:

      const int S = 10;
      int i[S];
       
      Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
      Copyright 1988-2007 Comeau Computing. All rights reserved.
      MODE:strict errors C99 noC++0x_extensions
       
      "ComeauTest.c", line 2: error: expression must have a constant value
        int i[S];
              ^
      Anyone have an explanation for this?
    2. 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.
    3. Re:Mostly agreed by Anonymous Coward · · Score: 0

      Easy: C doesn't have constants. Only readonly variables.

    4. Re:Mostly agreed by EvanED · · Score: 1

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

      This doesn't work if you're working on legacy code that must be compiled as C.

    5. Re:Mostly agreed by Sciros · · Score: 1

      I'm a bit rusty on my C++, but assert() statements in Java are discouraged in anything besides testing, since invoking them is a runtime config and is off by default in some environments. So, production code shouldn't have asserts() if it's Java.

      --
      I like basketball!!1!
    6. Re:Mostly agreed by EvanED · · Score: 1

      I should say that I'm not trying to be argumentative, just that overall "use this" rules (both use #define a lot and never use #define) are dumb.

      CPP macros are very useful even in C++ as a code generation technique for instance. Using them as constants or inline functions is bad practice, but there are uses.

      And in both languages, keep them distinct from names people might use independently. For instance, don't name a macro "current", lest you cause a newbie 15 minutes of frustration and swearing at GCC for nonsensical error messages. (I have to work that gripe into any discussion of CPP macros. ;-) )

    7. 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.
    8. Re:Mostly agreed by ookabooka · · Score: 1

      Don't use #define. Avoid it as best as you can. Use const int.

      Wouldn't that be slightly less efficient? Wouldn't that allocate memory to hold the value rather than having a literal in the program code? Would be disaserterous if it caused a cache-miss too, you coul lose a lot of efficency there. Anyone know how various compilers handle const ints?

      --
      If you are about to mod me down, keep in mind that this post was most likely sarcastic.
    9. 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.
    10. 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.
    11. Re:Mostly agreed by Anonymous Coward · · Score: 0

      Struct_t *ptr = malloc(sizeof *ptr);  -- This is the correct way in C, but it is invalid C++
      Struct_t *ptr = (Struct_t *)malloc(sizeof *ptr); -- Needed for C++

      In C the return value of malloc will always be correct for the pointer, casting the return value
      just hides bugs.

    12. Re:Mostly agreed by nonsequitor · · Score: 1

      Does the use of const int vs #define compile any differently? I work mostly with small embedded projects where every byte counts, though I've always trusted the compilers to handle the optimization and the standard seems to be #defines rather than const int across several companies I've worked at. Though IIRC #defines are resolved by the precompiler rather than the compiler which may result in smaller executable size since there would be less overall symbols in the symbol table. Since it may be that all constants with a value of 5 are resolved to the same one byte symbol, while if you have several constant int's with a value of 5 they each get their own word in the symbol table, depending on how smart your compiler is. That could be a legacy habit carried forward from older compilers though.

      The fact you can even use assert()'s means you work in a vastly different arena than myself, I'm lucky if I get more than 3 breakpoints at a time. So I do input sanitization similar to described in the article.

    13. Re:Mostly agreed by Anonymous Coward · · Score: 0

      remember, you don't have to use all the C++ features if you don't want to. I've often heard that excuse but it's not like they didn't come with any baggage at all.

      a) Someone else might use those features you didn't want to. In your project. Which you need to debug.
      b) The compiler needs to support all that extra shit too. Think that comes for free? Think again.
    14. Re:Mostly agreed by EvanED · · Score: 1

      the few things that won't (generally involving implicit casts to void*, as I understand it)

      It's not *hard* fixes, but it's a LOT of fixes. Every call to malloc for instance.

      There are a number of other things. "blah blah" has type char* in C, but const char* in C++. (There is a hack in C++ for this, but it's limited in scope.) C++ defines a ton of new keywords. 'a' has a different type, so any code that relies on the size will break. Same with enumerations. Functions with no parameters have type (...) in C but (void) in C++. C allows implicit conversions from int to an enumeration type. C structs are in a different namespace than variables and such, so you can have a struct S and a variable S and still refer to both.

      If you get into C99, things get much worse, because there are a lot of extensions it implements to C89 that are not in C++ (yet).

      I got into a debate on another site when I said that you could compile most decent C code as C++ with very few changes if only C++ allowed implicit conversion to void* for malloc purposes, and got reasonably schooled in that debate. There are a lot more differences than you might think, and they show up in most C code.

    15. Re:Mostly agreed by 91degrees · · Score: 1

      Does C99 allow you to assign a const's address to a pointer? That would cause problems if it was hard-coded. "*((int *)&my_const) = 3;" would mess up your array bounds quite horribly. Personally, I think a language should prevent that sort of travesty of code, but I'm not on the C99 committee.

    16. Re:Mostly agreed by EvanED · · Score: 1

      Does the use of const int vs #define compile any differently? I work mostly with small embedded projects where every byte counts...

      If you're doing embedded stuff, you would be well served to check it out. My feeling is that any compiler worth its salt would be able to optimize away at least almost all occurrences, and probably all occurrences, of a const. I suspect it would then get rid of the constant from the executable, but I'm not sure. You would have to test it with your compiler. (It almost certainly would NOT remove the constant if you ever take the address of it though.)

      But, if you're working on embedded stuff, you're probably using C instead of C++, which means you're subject to the broken const int I mentioned in a previous post (where you can't use it for array bounds) so you'll have to use #define some of the time anyway.

    17. Re:Mostly agreed by EvanED · · Score: 1

      Yes, but C++ has the same problem. The code you gives compiles with C++.

      And even if you buy that this is the reason they don't let it be used for array bounds, there are still plenty of other constants that you could screw up with equally devastating results.

    18. Re:Mostly agreed by Anonymous Coward · · Score: 0

      For instance, don't name a macro "current",

      Heh, the best one I encountered was the idiot imbecile moran retard who made a macro named 'i'. Yup, as in 'int i'. From the way he used it, it wasnt even meant to be funny. Something about setting up a table of int data and pointers. He had a,b,c...

    19. Re:Mostly agreed by dkf · · Score: 1

      If you've got a 'const int' there's no guarantee that even if you cast the constness away that you'll be able to write to it. The compiler could well have decided to put it in read-only memory.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    20. 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.
    21. Re:Mostly agreed by Tom · · Score: 1

      Very strong disagree on assert() there.

      A lot of errors don't necessitate a program termination. Depending on your program, it might be very much better to log the error and carry on.

      --
      Assorted stuff I do sometimes: Lemuria.org
    22. Re:Mostly agreed by drxenos · · Score: 1

      There is no reason to assume that just because his project is embedded that he is using C and not C++. The C++ standard defines the same support for stand-alone (non-hosted) systems as C does. C++ is used in a great many embedded systems. We use it all the time.

      --


      Anonymous Cowards suck.
    23. 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.
    24. Re:Mostly agreed by Anonymous Coward · · Score: 0

      In my projects I replaced this about 500 times
      const CString blah = "SomeString";
      with
      #define blah "SomeString"

      Turned on string pooling in the linker, fixed everyone who was changing the string, and saved 5 meg of code and page space.

      Do not give me that demand page loading crap. const can be abused JUST as much as define. As every reference to the above causes a few dozen method calls, never mind start up performance. If its const it PROBABLY can be a #define. But you do not want that all the time... Such as in my example I left a few of those CStrings as they needed to be that way. But 99% of them were being passed into a set of printf statments.

      I have also seen the inverse where #define is abused and needed to be replaced with function calls. 20meg to 2meg and a decent speed increase. But mostly it was the 3 hour saving on build time that we liked.

      But really it comes down to not a blanket rule but using your tools in the proper way.

      I also hurt people who use 'i' for loops. Is it a 1 or i or l? My eyes are not that good anymore :(

      Like the ASSERT thing. But what about when your code ships? You need both.

    25. Re:Mostly agreed by Anonymous Coward · · Score: 0

      Heh, the best one I encountered was the idiot imbecile moran retard

      Bet he knew how to spell moron, though...

    26. Re:Mostly agreed by ZorbaTHut · · Score: 1

      const char *const blah = "somestring";

      Yes, obviously using CString is going to take a significant amount of code and memory, because CString isn't a primitive, has a (very) nontrivial constructor and destructor, and therefore can't be inlined by the compiler. That's why you don't use it for a lot of global constants. You could argue that using char* strings is going to be a problem in some way due to the missing members, but the fact that the #define works indicates to me that it generally won't be - so the const char*const should work fine.

      Personally, I leave assert()s in with final code. Why not? If there aren't bugs, they won't be hit anyway. If there are bugs, I'd rather the program crashed cleanly and quickly - far better than running wild with corrupt data and unknown state. I try to rig my assert-equivalent to emergency-save whatever it can, so, really, hitting an assert is the best possible result for a bug. Why remove that? That would just be dumb.

      No, there are no universal rules. That's why I said 99%.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    27. Re:Mostly agreed by Anonymous Coward · · Score: 0

      I did not say take out the asserts... I use them to death. I asked what do you do when SHIP code blows up? Do not discount it. I use the approach of log the hell out of it AND assert.

      Most C/C++ headers have something like

      #ifdef DEBUG
      #define ASSERT bunchofcooldebugstuff();
      #else
      #define ASSERT
      #endif

      Also const can be bad in this way

      const int xyz = 3;

      somefunc()
      { // fix some stupid compiler bug
            int *pxyz = (int *)
            *pxyz = 4;
      }

      I have seen this. If it was a #define he would have know RIGHT away that what he was doing was bad. But knowing the guy he would have somehow bashed it up wrong anyway :)

      Whenever I see 'const' I assume that I will end up with code (not always) but will always end up with some data location somewhere. Also many times these things get drug up into some header somewhere. Oh goody its in all 100 .cpp files. So now I have 100 4 byte blobs of memory created all over the place in every .obj file. Is that alot? Not really but some projects have thousands of const like values. It adds up. If you wanted the best of both worlds you probably could jury rig some defines to get it.

    28. Re:Mostly agreed by nonsequitor · · Score: 1

      I meant symbol table in regards to the compiler's parsing of the code using the grammar and representing the various expressions in a tree format. The exact terms escape me at the moment.

      We use C mainly because the C++ compilers available for the architecture suck when compared to the C compilers for code size and speed. And when you only have 2K RAM and 32K ROM, efficient compilers are very important.

      I've seen C++ used on project for embedded x86, but that's the only time I've seen it used. And for Embedded x86 they will go ahead and make the jump to C#.NET if its a Windows platform, just because good C and Assembly programmers are scarce these days and .NET is managed which can prevent a lot of problems if you have the resources in the device to run it. It also causes lots of problems, but thats because its MS. As an added bonus, if you work for a Fortune 100 company with Enterprise Support for XP Embedded you get to yell at the developer over the phone who "Designed it not to work that way" over at MS ^_^

    29. Re:Mostly agreed by ZorbaTHut · · Score: 1

      Ah, fair enough. I don't actually use assert(), I have my own equivalent function that doesn't go away in release mode. So that isn't so much of a problem.

      How would define have helped in that situation? I don't even see the token "xyz" existing anywhere in that code, besides in the const. Maybe Slashdot formatting broke it?

      I believe that the linker pushes all those variables into the same section - a thousand 4-byte "blobs" will end up sitting end-to-end in a nice 4k memory area, taking not a lot of space. Globals are much nicer than dynamic allocation in that sense. That said, a true const int will likely not even exist in the program in the end - it'll be inlined into every function.

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

    31. 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?
    32. Re:Mostly agreed by drxenos · · Score: 1

      Well, the parse tree isn't stored in the final code. If you mean the symbol table built into the code file, then the local symbols may be striped out without harm. Regardless, the local symbols are not normally loaded in RAM anyways.
      Regards,
      DrX

      --


      Anonymous Cowards suck.
    33. Re:Mostly agreed by Anonymous Coward · · Score: 0

      Get a brain, moran...

    34. Re:Mostly agreed by Anonymous Coward · · Score: 0
      Unfortunatly it can not be inlined. As lets say you have something like

      const int xyz = 3;
       
      void Blah(int *pAbc)
      {
          *pAbc = 99;
      }
       
      then somewhere else you go
      Blah((int*)&xyz);
      There MUST be a place to put that 99. As C *LETS* you break the const semantic.

      Also unfortunately compilers are not that good at snorking it all up into 1 4k page. I wish they were. However lets say you put 'const int xyz = 9;' into a header. EVERY single place you include that const will include 1 copy of that xyz. It must. So if you include that same .h file in every one of your .cpp files you will end up with 1 4 byte blob in every .obj file. Most compilers do not do cross file optimization. Even GCC does it only on a very limited bases. Most linkers have very simple passes create code pages, create data pages, glue all obj files together one after another. Now on some archs they require 1 large code page so the linker may move the code pages around. But very rarely do they scrunch them together. Then fix up the pointers to all the vars. Plop a startup chunk of code at the front for setup and poof you have an exe. Some archs are even worse as they make you put things on 8/16 byte boundaries. And all of those things will end up taking 8 bytes when you think they take 4. What happens usually is one 4k code page per .cpp. They might be end to end. But usually 1 for every cpp.

      Also what if someone says 'extern' to that same var? There must be a chunk of memory allocated for that var. Otherwise you would not be able to get a pointer to that variable. In this case it is just an int, but what if it is a struct or string? The compiler might inline it but I highly doubt it unless it can trace every path and insure that no one has changed that memory. As you *can* break it with casting and other pointer magic. Also this is how most exploits get traction on a system. Using stings and piggy backing into code through a buffer over/underrun into a string. Then using that place as a launching point into unexpected code. As the string MUST live somewhere in memory.

      I have lately treated const as a 'nice' suggestion to the local function to say 'i will not change this var in here' But to rely on it as anything more is begging for trouble.

      Its all pretty interesting once you dig underneath and see what the compiler is really doing to your code.

      cool slashdot does eat that bit, & xyz; was what I wanted :)
    35. Re:Mostly agreed by ZorbaTHut · · Score: 1

      There MUST be a place to put that 99. As C *LETS* you break the const semantic.


      This is actually partially incorrect. In C++, at least, removing the const from a pointer is undefined behavior (at least in the case where the pointer actually points to a const object, I'm not sure what it does if the pointer points to an object which could theoretically be modified.) The compiler is well within its rights to store that value in a constant data segment, and it's well within its rights to make that code you posted do something horribly wrong.

      However, just taking the pointer in the first place does, indeed, require that it has some existence in memory. So you're right that there must be a place to put the 99, but not because C++ lets you break the const semantic - especially because C++, in fact, doesn't let you.

      const is two things. It's telling the local function "you're not allowed to change this", and it's telling the caller "it's not allowed to change this". Things might still get changed, but if they do, it's the sign of a hideously broken program.
      --
      Breaking Into the Industry - A development log about starting a game studio.
    36. Re:Mostly agreed by try_anything · · Score: 1
      No side effects other than halting the application, you mean ;-) To expand on your statement, the optional nature of asserts means you should:

      • Never put important checks into asserts whose compilation status you don't control.
      • Never use asserts to check for errors originating in other modules. (I usually go much further than this and only use asserts to check for errors originating in the same function (for free-standing functions) or class (for member functions).)
      • Never use asserts to check for conditions that might be caused by user error or external conditions.
      • Never use asserts to guard against conditions that are recoverable. (If you are ever tempted to catch and handle an assertion failure, it should be converted into a normal exception. Assertion failures should never be caught and handled, except by handlers that can log extra information before rethrowing, or log the assention info into a sink that the throwing code didn't have access to.)

      Basically, you should only use assertions for checks that can be removed when the module is declared bug-free. I follow this practice even though I never plan on declaring my code bug-free (hubris!), because I know that developers succeeding me might assume it is reasonable to turn off assertions in stable code.

      Another good idea, though I have never had a need to use it myself, is to create two categories of assertions: those that have been shown to affect performance, and those that presumably do not affect performance. This is a good way to profit by the 90/10 rule, and a good way to placate weirdos who think that safety and speed are eternal enemies, locked in a battle for the soul of software, instead of desirable qualities that occasionally must be traded off against each other.

    37. Re:Mostly agreed by Yunzil · · Score: 1

      I also hurt people who use 'i' for loops. Is it a 1 or i or l? My eyes are not that good anymore :(


      I was with you up to this.

    38. Re:Mostly agreed by Thunderbear · · Score: 1

      Would be disaserterous if it caused a cache-miss too, you coul lose a lot of efficency there. Now THAT is premature optimization indeed :)
      --

      --
      Thorbjørn Ravn Andersen "...and...Tubular Bells!"
    39. Re:Mostly agreed by TemporalBeing · · Score: 1

      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!
      Absolutely WRONG!!!!

      Assert()s are okay in a very, very limited scenario - but if you are writing truly robust code, you will do whatever you can to handle any error. If you end up in a state that you do not know, then error out and say it - the level above you might know what to do, and it may not be crash the program. At least with warning messages you have something to go on when (a) debugging and (b) maintaining the program.

      Furthermore, Assert() is usually optimized out for "release" builds to no-op's. So then what happens if the condition didn't occur in your debug build (where Assert() would have theoretically caught it) but does happen in the release build? What happens if it happens in your customer's environment, but not in your environment because the timing is different?

      Really, the only true answer is get rid of assert() - it's a classroom toy - and do the job right - handle the error like a man (or woman). There is no excuse for not writing robust and maintainable code, and as the author of the article points out - you'll love yourself if you do, and hate yourself if you do not.
      --
      Truth is like the sun. You can shut it out for a time, but it ain't goin' away. - Elvis Presley (source: imdb.com)
    40. Re:Mostly agreed by ZorbaTHut · · Score: 1

      Point 1: I disagree strongly. If you end up in a state that you don't understand it's entirely possible you've clobbered other parts of the code - perhaps data structures are no longer sane, perhaps you've overwritten random parts of memory, perhaps you're simply in a situation that nobody has ever conceived of. In any case, if you're in an unknown state, the function has failed in a way which could not have been foreseen, and therefore anything you do from there is just wandering around in the dark hoping that maybe somehow things work out.

      Point 2: You're right, it is. That's why I have my own assert()like macro that doesn't get optimized out in release builds.

      Point 3: The right thing to do is define "error" properly. Something going wrong in the function isn't an error. It's an expected case. It should be dealt with properly. Something utterly unexpected and impossible going wrong? That's an error.

      If I get internal consistency faults in my program, it damn well should crash because nobody will be able to trust what it does next. Of course, that shouldn't be possible, but I've found by far the best way to keep internal consistency faults away is to make sure that they're detected ASAP and fixed. And that's where asserts come in.

      --
      Breaking Into the Industry - A development log about starting a game studio.
    41. Re:Mostly agreed by TemporalBeing · · Score: 1

      If I get internal consistency faults in my program, it damn well should crash because nobody will be able to trust what it does next. Of course, that shouldn't be possible, but I've found by far the best way to keep internal consistency faults away is to make sure that they're detected ASAP and fixed. And that's where asserts come in.
      And when are you doing these checks? At the start of a function - verifying the input? If so, then a return value works better and lets the caller handle the issue, and you've done minimal efforts. You can also protect your code against bad data easily this way.

      Now, if you are performing a sanity check in the middle of a function - that could be a different issue. But if your function called another function, and that function did something...well...checking the error codes from the return should give you what you need to know. It may be that you continue and escalate the error out, and ultimately terminate the program. But TRY to handle all the errors you can.

      Unknown errors are not always bad things. It could be that the API changed slightly and added a new error code that you don't yet handle. Such a code should be brought to the user so that it can be reported to the support team so that it does get handled.

      Now, if you are able to magically determine that someone has clobbered your entire system - that would be great news to share with the rest of us. Me? I stick to what I've said about asserts - and I've written successful programs accordingly so I do know what I'm talking about.

      I've also laid out frameworks from which programs will be built. If you handle it early on (without asserting) you have a far better chance of being able to handle it. Furthermore, if you do your defensive programming right (e.g. everything is checking the input values to verify before doing any processing), then you will catch the error before it causes a problem; and if you check the errors returned properly, then you can report what the real issue is.

      If you are doing your coding right - then you are checking inputs to functions and outputs of functions. If your coding is right, then you will catch an out-of-bounds error BEFORE it clobbers your stack, and you will catch the invalid pointer BEFORE it causes a seg-fault. Anything else is laziness of the programmer.

      So, I still propose to you that Assert()s are absolutely wrong. There are far, far better ways to handle the issues.

      The only time software should truly error out - is when the hardware fails. Software should be able to catch and handle everything else; if it doesn't - the programmer who wrote it is too lazy. This means that programmers of all levels of the system must ensure the software does its job to catch and handle the errors and do so appropriately. Assert() is not appropriate in 99+% of cases.
      --
      Truth is like the sun. You can shut it out for a time, but it ain't goin' away. - Elvis Presley (source: imdb.com)
    42. Re:Mostly agreed by ZorbaTHut · · Score: 1

      I use 'em all over the place. In the beginning of functions, in the middle of functions, at the end of functions. I actually have functions whose sole purpose is to double-check consistency after I've done something nasty (although I do try to avoid this.)

      Internally, in my programs, I should never be calling a function with invalid input. Ever. So when I put an assert to check for that, it's an instant-crash assert, because it means I've done something horribly wrong. Obviously talking to an external API is potentially a different matter (although in that case you could still argue that "omg I have no idea what this means abort abort abort" is the right behavior) - but internally I shouldn't be passing error codes around because there shouldn't be errors.

      I've written successful programs also, so I'm pretty sure I know what I'm talking about also. However I highly doubt either of us are going to convince the other.

      I believe that assert()s should never, ever trigger, and should be used extensively to verify internal consistency and expected results.

      (Also, there's no way to detect an invalid pointer in pure C++. NULL, sure. Invalid? Nope.)

      --
      Breaking Into the Industry - A development log about starting a game studio.
    43. Re:Mostly agreed by TemporalBeing · · Score: 1

      internally I shouldn't be passing error codes around because there shouldn't be errors.
      True, there should not be. However, timing and other environmental effects in which the software runs could cause such errors. So, doing so and treating your own code like you would external code makes the program stronger, safer, less problematic, and more robust overall. Trusting any code - internal or external - is an error itself, at least IMHO.

      (Also, there's no way to detect an invalid pointer in pure C++. NULL, sure. Invalid? Nope.)
      True, you can only check whether a pointer is NULL in C or C++. Truthfully, I think the base libraries (e.g. standard C lib, etc.) should be able to tell you what the sizes of the memory chunks are that the pointer points to, and whether or not the pointer is valid in the sense of (a) if it was free'd, and (b) it is heap or stack memory - it would be very helpful to have a call(s) do to so. This should be easily extendible from the OS memory management functions, as well as the base libraries' own wrappers to those functions (e.g. C's malloc/free, C++'s new/delete, etc.).

      But, since we cannot do that as yet, we can check whether the pointers are valid - in the sense of NULL or NOT NULL - and handle appropriately. Also checking that data is within valid ranges, and checking that double pointers are what is expected too.

      Now, if you were to do this on all your functions at start/end whether or not they are internal or external, and generate and handles errors in all locations, then you should, more likely than not, not need to do the consistency checks in the middle of your functions and your programs should be able to die gracefully without crashing, allowing you to put data into the logs, etc. so you have better data to go on when you are trying to figure out what the problem(s) was(were) that caused it.
      --
      Truth is like the sun. You can shut it out for a time, but it ain't goin' away. - Elvis Presley (source: imdb.com)
    44. Re:Mostly agreed by drxenos · · Score: 1

      Do I know what it means? Um, yeah, I've been writing embedded systems for 15 years. First, C++ does not require you to write OO programs. Second, there is no reason to believe an OO program is larger than an equivalent non-OO program. Third, listing the size of the entire C++ library means nothing. You don't have to, and certainly shouldn't use the ENTIRE library. Fourth, that is the C++ shared library for a HOSTED system. Like C, the C++ standard provides for free standing systems. My C++ library for our targeted system is much smaller than that. And Fifth, 1MB? Valuable? Some of the embedded systems I've been involved in have 1/2 GB of memory or more. Embedded does not necessarily mean resource starved. Clearly, as I stated, know-nothing nonsense. You don't seem to know jack about C++, OO, or embedded systems.

      --


      Anonymous Cowards suck.
  11. Updating comments... by Etherwalk · · Score: 1

    Um... well, duh.

    But aside from simply commenting, *updating* comments is also important, and possibly more so. Looking at the history of the TCP/IP source in OSX, for example, you see wonderful instances of complex code that's been updated as new operating systems have been built on top of it, but comments reflect the old behavior rather than the new.

  12. It's very simple by Anonymous Coward · · Score: 0

    A good programmer writes code to be executed efficiently by a machine.

    A master writes code to be read efficiently by human beings.

    That is all.

  13. 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 AP2k · · Score: 1

      That is bad in a way because the const ints are being stored in memory instead of hardcoded at compile time. Its not such a bad thing these days with monsterous hardware, but it is a habit that needs to be broken. 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.

    2. Re:I thought #defines were deprecated in C++ by 19thNervousBreakdown · · Score: 1

      Wrong.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    3. 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
    4. 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.
    5. Re:I thought #defines were deprecated in C++ by sconeu · · Score: 1

      #define SIX 1 + 5
      #define NINE 8 + 1
      printf("%d", SIX * NINE)
      Which helpfully prints "42" instead of 54.

      By Zarqon! You've solved the mystery of the Great Question of Life, the Universe, and Everything!
      --
      General Relativity: Space-time tells matter where to go; Matter tells space-time what shape to be.
    6. Re:I thought #defines were deprecated in C++ by drxenos · · Score: 1

      I'm sorry, but you really don't know what the hell you are talking about. There is no requirement by the C++ standard that the constant be "stored in memory." They are often "hard coded" inline and not stored, unless they are 1) large or 2) have their address taken. DrX

      --


      Anonymous Cowards suck.
    7. Re:I thought #defines were deprecated in C++ by Anonymous Coward · · Score: 0

      That is bad in a way because the const ints are being stored in memory instead of hardcoded at compile time.

      Even if they ARE compiled so that they are in memory... if you actually have memory problems on non-embedded systems because of it, I think you have a far bigger problem.

      Namely, trying to hardcode a ludicrous amount of information. What next, complaining about how comments are slowing down your build process?
    8. Re:I thought #defines were deprecated in C++ by tepples · · Score: 1

      [Whether reads from constants are optimized out is] implementation dependent, and as long as you're compiling with optimization, you're probably wrong most of the time. Unless a const symbol is defined in one module and its address is taken in another module. But what you say is true for static const symbols.

      consts are typesafe A #define can also carry type information:

      #define SIX (int)(1 + 5)

      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. If you don't have to worry about C compatibility, then you are limiting your market for the library. To define numeric constants, a lot of C programmers use enum.
    9. Re:I thought #defines were deprecated in C++ by tepples · · Score: 1

      Wrong. Citation needed.
    10. Re:I thought #defines were deprecated in C++ by tepples · · Score: 1

      There is no requirement by the C++ standard that the constant be "stored in memory." Are const objects automatically deemed static (that is, visible only within one translation unit) in C++? They aren't automatically static in C, and another translation unit that is linked into the same executable might declare the constant with extern const and then take the address of the object. I know at least the GNU linker doesn't optimize out dead code or dead data in the same translation unit as live code or live data.
    11. Re:I thought #defines were deprecated in C++ by drxenos · · Score: 1

      That's one difference between the two languages. In C++, const has local scope by default. In C, const is extern by default. About "taking the address": see #2 of my full comment.

      --


      Anonymous Cowards suck.
    12. Re:I thought #defines were deprecated in C++ by Anonymous Coward · · Score: 0

      Even if they ARE compiled so that they are in memory... if you actually have memory problems on non-embedded systems because of it, I think you have a far bigger problem.
      It's not the memory. It's the register usage and cache misses.
  14. The code should be the comments by Normal+Dan · · Score: 1

    In his "player_bullet::move_it()" example he should have moved all of his "[Small chunk of code.]" sections into a new function. Then, he could have called a function named "Calculate_bullets_new_position". This way, he is using the code to comment. It is much cleaner and easier to understand. Functions should rarely, if ever, have comments in them.

    --
    A unique way to learn a language: http://languageloom.com
    1. Re:The code should be the comments by geekoid · · Score: 1

      simpler to debug as well.
      Many small functions is almost always better then one long 1600 line function.
      Yes, I have actually seen 1600 line functions...NOT counting empty lines.

      Fortunately it was loops inside several other loops using a goto statement...

      I don't know who to be more mad at, the developer or the manager who forbid anyone from actually redesigning it into smaller piece. The simplest of problems would take days to find, and then days to test because there was always sever unintended results that effected some screen that doesn't have the problem you are working with.

      no, the coder is who I am madder at. The fact that he still got 2500 dollars a sale, and 5000 dollars a month 'retainer' makes me mad...and jealous.
      I put retainer in quotes because he was useless when trying to fix his code.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  15. 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.

  16. Too basic, and then not far enough by Mycroft_514 · · Score: 1

    What about structured coding? I mean really, this stuff is so obvious, and then to not even mention structured coding?

    1. Re:Too basic, and then not far enough by Fizzl · · Score: 1

      Holy shit! This man is a genious! Mod +5 interemightful!
      Structured coding! Why they didn't thought of that!?

      Adding 0 to 0 is still 0.
      Thank you captain obvious.

      (What the hell is structured coding anyway? You mean those newfangled classes and objects and stuff I've heard about?)

  17. 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?

    1. Re:At this point I am thinking by Llywelyn · · Score: 1

      Everyone may know it, but if I had $1 for every time I've seen any of these horribly violated by someone with over a year of programming experience and a C++ degree, I'd be rich.

      --
      Integrate Keynote and LaTeX
  18. "Comment like a smart person." says article... by aabxx · · Score: 0

    which, for me at least, takes more time away from trying to figure out what the goddamn code actually says.

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

    1. Re:Actually by bill_mcgonigle · · Score: 1

      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.

      Geez, and I thought Skynet was just doing garbage collection.

      --
      My God, it's Full of Source!
      OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
  20. 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 Dancindan84 · · Score: 1

      The point was that if they're starting their careers and aren't aware that keeping clean, commented, modular code is a fundamental part of programming there's something seriously wrong.

      It'd be like having an article on a site for math major graduates covering multiplication. This is the developers section of slashdot, not a high school programming for dummies textbook.

      --
      "Always forgive your enemies; nothing annoys them so much." - Oscar Wilde
    2. Re:It was fine... by Anonymous Coward · · Score: 0

      Let me save the grandparent the trouble of generalising his comment.

      High school programmers are allowed to read articles too.
      People who want to learn to program but never took a programming class in high school are allowed to read articles too.
      People whose programming abilities are seriously deficient are allowed to read articles too.
      Amateur programmers—who have no programming careers—are allowed to read articles too.

      Basically, everyone who can read or has access to someone who can read for them are allowed to read programming articles. Are you honestly saying that every man, woman and child in the world who has even a passing interest in writing code is already familiar with the advice in the article? I know that when I first started programming, there was a point at which this advice would've been useful to me. It's good advice, even if it's fairly basic stuff that many people will have heard before.

      (Also, if you look around the net for horror stories from people who have to maintain code written by professional programmers, you'll discover that professional programmers who do not follow these rules clearly do exist. Everyone may have heard the advice before, but some have pretty clearly not taken it to heart, and they could stand hearing it repeated by a source they may respect as a coder. (The author has programmed several pretty successful indie CRPGs more or less by himself.) )

    3. Re:It was fine... by PitaBred · · Score: 1

      And if people can't look in front of them to tell that the cars are stopped, there's something seriously wrong. Brake lights still help.

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

    5. Re:It was fine... by bensch128 · · Score: 1

      Yes, beginners should be reading articles like this but this is a couple of years out of date.
      Review by section:
      1) Comments = Good
      2) Not using magic constants is good. Using defines is BAD! Use static const instead. Then you get static type checking and when using your debugger, the value of the variable with actually appear. Even better, use a config file and a settings mechnisism so you can the game parameters without a recompile.
      3) Nice sized variable names = good. Hungarian notation = BAD. Any decent modern IDE will have a "Goto declaration" function. Use it. If your IDE doesn't have that function, throw it out and quickly find out that does (kdevelop, slickedit, modern VC++, etc..) There's no reason to write obfuscated variable names because of bad technology (M$ VC 6.0)
      4) Silent returns = bad! Proper error checking and handling = GOOD. In his simple case, he should be using an assert or better yet, throwing an exception. Ideally, he will properly handle the exception too.
      5) this is well done, whether he quoting knuth correctly or not.
      6) This is correct too. HOwever, I have to point out that he forgets to defensively add braces to some of his for loops and if statements. Unbraces control statements is asking for bugs to occur later on, especially when commenting blocks of code begins to happen. Please, please add braces around all expressions following a control statement and save a poor maintainance programmer's sanity.

      Lousy article. Gets 2 out of 5 from me.
      Ben

  21. Ok. by grumpyman · · Score: 1

    So where can I download "Kill Bad Aliens"?

    1. Re:Ok. by evil_aar0n · · Score: 1

      The nice folks over at scientology.com should be able to help.

      --
      Truth, Justice. Or the American Way.
  22. Bringing things together by Coryoth · · Score: 1

    It is notable that Tip 1, "Comment like a smart person", and Tip 2, "Do error checking. You make errors. Yes, you" can be sensibly combined into "Use contracts". Sure, you'll still need some extra comments to describe the function, but any comments about the parameters a function recieves and what it returns can be usefully written as contracts which provide both documentation and error checking. It also helps you to think about exactly what you intend a function to do, and assists greatly down the line when re-using code by providing clear testable constraints on what a function can and cannot do so you don't accidentally go misusing it.

    1. Re:Bringing things together by tepples · · Score: 1

      Tip 1, "Comment like a smart person", and Tip 2, "Do error checking. You make errors. Yes, you" can be sensibly combined into "Use contracts". True, DESIGN BY CONTRACT® methodology, Some hardware platforms, especially handheld and embedded platforms, lack a decent runtime environment for the Eiffel language. True, in C or C++ one can assert() to check pre- and post-conditions in a debug build at runtime, but that can interfere with the performance of real-time software such as a video game engine or a brake control program. Are there any decent compile-time contract checkers for C, C++, or Java?
    2. Re:Bringing things together by Coryoth · · Score: 1

      Are there any decent compile-time contract checkers for C, C++, or Java? There is for Java in the form of ESC/Java2 which checks contracts and frame conditions in the form of JML annotations. It's not perfect (and at the moment only works for Java 1.4, apparently 1.5 is forthcoming), but it does a surprisingly good jo of weeding out subtle errors.

      but that can interfere with the performance of real-time software such as ... a brake control program. If you're working with safety critical realtime software I would suggest you look at SPARK/Ada which provides very strong static checking of contracts for Ada.
  23. 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 Anonymous Coward · · Score: 0

      C has structures and function pointers ... same thing as classes and methods.

      Ever heard of XWidgetCreate() or XWidgetDestroy()? Combined with stuct Widget{}, you're good to go.

      In the beginning of C++, we were still using X/Windows as a pseudo-template for object oriented programming. Heck, C++ was just a C pre-processor.

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

  24. Self documenting code? by mattoo · · Score: 1
    I'll take:

    // returns TRUE if the bullet is to be erased (because it hit a target or the top of the screen)
    Boolean player_bullet::move_bullet_upward()
    {
    Boolean is_destroyed = FALSE;

    Pos new_pos = calculate_new_position();

    if (contains_enemy(new_pos) {
    destruct_enemy(new_pos);
    is_destroyed = TRUE;
    }

    [..]

    Return is_destroyed;
    }
    over:

    // 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.
    Boolean player_bullet::move_it()
    {
    Boolean is_destroyed = FALSE;

    // Calculate the bullet's new position.

    [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]

    [..]

    Return is_destroyed;
    }
    any day of the week.
    1. 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
  25. 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
  26. 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.

  27. 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>
    1. Re:Obvious and Wrong in One by harry666t · · Score: 1

        int c = 0x05;
        printf ("%d%d%d%d\n",4/c--,++c-c*2,c-c+c--,--c-1+c--);
        // and the result is...

    2. Re:Obvious and Wrong in One by EvanED · · Score: 1

      // and the result is...

      The result is... implementation dependent!

      Any one of 24 potentially different outcomes may occur.

    3. Re:Obvious and Wrong in One by EvanED · · Score: 1

      (And potentially it's undefined behavior. Now that I think about it again, evaluating '++c-c*2' may provoke undefined behavior. I'm pretty sure it at least will add a few new axes to the possible outcomes.)

    4. Re:Obvious and Wrong in One by merreborn · · Score: 1

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


      In my earlier years, I might have said the same thing about the ternary operator. Its syntax is a touch obscure, by which I mean, they don't teach you about it in programming 101.

      However, once you're familiar with it, it allows you to do in one line, what might have taken 4 before. Which actually makes your code *more* readable.

      Long story short, you have to strike a balance. You can't do everything in one line, as your code becomes too dense and unreadable. But you can't do too little either -- a whole if-else where a ternary would do takes *longer* to read. Similarly, proper use of increments can save you extraneous code.
    5. Re:Obvious and Wrong in One by Doctor+Faustus · · Score: 1

      But you can't do too little either -- a whole if-else where a ternary would do takes *longer* to read.
      No.

      I did actually start using the ternary operator a bit the last time I worked much in C++. I got in the habit of declaring most of my local variables as const, and the ternary operator lets you go further that direction.

  28. Was Jeff Vogel the "anonymous reader?" by Anonymous Coward · · Score: 0

    Just wondering... because, offhand, I can't think of any other obvious reason to remain anonymous.

    Just as I always wonder whether the people who find those amazing Easter eggs in programs were able to find them because they put them there themselves...

  29. Tip #1 by Anonymous Coward · · Score: 0

    Use java

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

  31. Must comprehensible code compile? by quartic_influx · · Score: 1

    error: 'I' undeclared (first use in this function)

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

  33. Re:Use a language that checks I/O errors by defaul by LiquidCoooled · · Score: 1

    Additional to this, if the 'nice' language features give the user an error message and bails, what happens to the intermediate steps you were performing?
    Not everything fits inside a nice transaction and sometimes things need cleaning up.
    It might be the final step in a long list of sequential actions, or it might just be a few easy steps but you can be sure of one thing:

    If your program keeps kicking them totally out of the system (no matter how 'nice' the message) for a stupid simple handleable errors they will be pissed off.

    --
    liqbase :: faster than paper
  34. /* comment */ by GillBates0 · · Score: 1

    /* insert meaningful and descriptive comment here */

    --
    An Indian-American Hindu committed to non-violent thought/speech/action alarmed by the global explosion of radical Islam
  35. Noooooooooo by Anonymous Coward · · Score: 2, Funny

    In Soviet Russia, Code comments YOU!

  36. I remember when by Dunbal · · Score: 1

    the foremost concern of any programmer used to be time. CPU time. How many cycles for this operation, versus how many cycles for that one. Now it seems like we have shifted our time concerns to programming time - the programmers' salary, the time to market, etc. Funny though how this tends to result in bloated, sluggish, bug-ridden programs that need at LEAST a patch or two before they even reasonably deliver what was promised on the box.

          I guess we are lucky that the software "consumer" (and I use that word with the greatest contempt) has been "educated" to EXPECT a certain amount of crashes and bugs, and even DEMAND that the latest software come on 3 or 4 CDs instead of just one. I mean WOW, more is better, right? I wonder, however, which other industry (apart from maybe Hollywood) can get away with this? But sheep are sheep, and they will continue to eat what we feed them.

    --
    Seven puppies were harmed during the making of this post.
    1. Re:I remember when by Anonymous Coward · · Score: 1, Insightful

      Funny, because I also remembered when programmers, so concerned with CPU time, would cut out checks, mess with code until it worked 'right' and would generally tweak it until it worked, to their mind, perfectly. But in fact would crash on unusual conditions or outright produce incorrect output. But it was fast. Fast and wrong. And often times the 'optimizations' they were doing were not anything that really affected performance. First rule of optimization, don't until it's proven needed.

      We end up with so much bloated, broken code because people don't worry about right before 'performance' or 'reusuablity'. Get it right and you'll find a lot of the rest of it comes from that. Including maintainability. The best maintainable code package I worked on also happened to be the fastest(faster by an order of magnitude) over the original. The new code was also object oriented, extensible, clean and actually correct(original didn't accurately calculate a value right).

      So I don't think that developers are any different than they used to be. They just write more code that's wrong, bloated and crappy. It just has a prettier interface, more colors when it explodes and more features that never get tested or used.

  37. do you color your hair with rainbow colors? by Anonymous Coward · · Score: 0


      ???????????

    Reason: Your comment looks too much like ascii art.

    Reason: Your comment looks too much like ascii art.

    Reason: Your comment looks too much like ascii art.

  38. 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 EvanED · · Score: 1

      Expressions are like sex: they're better without side-effects.

      I think this should be the slogan of Haskell or something like that. I think I have to steal it for something.

    2. 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>
    3. Re:Felt I should point out by Anonymous Coward · · Score: 1, Interesting

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

      I think you're just not familiar with the terminology here. Anything that is observable outside of an expression other than through the returned value is a side effect. If you call puts("foo"), printing foo to stdout is a side effect even though it's the whole point of the function call.
    4. Re:Felt I should point out by Anonymous+Brave+Guy · · Score: 1

      First off, it is a side effect, according to the usual definition of that term in computer science.

      Secondly, it's not just syntactic sugar, either. The increment and decrement operators are separate things to addition and subtraction, and this is particularly relevant in C++ where you may have a type that understands the concepts of "next" and "previous" without having any concept (or even any defined operator) for addition or subtraction. Iterators that do not admit random access are a typical example.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    5. Re:Felt I should point out by Doctor+Faustus · · Score: 1

      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.
      That's a necessary complexity, though. All the smartass little shortcuts C has built in don't actually make it more efficient or let it do anything it otherwise couldn't.

    6. Re:Felt I should point out by Rudisaurus · · Score: 1

      ... 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.
      Bullshit. It's part of the syntax and an accepted construct in the language. Just because the semantics are a bit obscure to a beginner doesn't make them invalid or useless. Compact and sparse code has an elegance of its own, and being able to write it well is part of the joy of programming.
      --
      licet differant, aequabitur
    7. Re:Felt I should point out by loqi · · Score: 1

      It's part of the syntax and an accepted construct in the language.

      Of course it's part of the syntax. So is goto. As for "an accepted construct in the language", I'd say that's pretty subjective.

      Just because the semantics are a bit obscure to a beginner doesn't make them invalid or useless.

      This has nothing to do with beginners, and everything to do with the fact that code is meant to be read. Throwing increment operations into an expression forces the reader to mentally "factor" the code into its two logical components: the value of the expression, and the side-effects of the increment, without any real textual/visual distinction between the two. This is simply unnecessary when it's so trivial to more clearly express the intent with multiple statements.

      Compact and sparse code has an elegance of its own, and being able to write it well is part of the joy of programming.

      Here's my take: "Concise code has an elegance of its own, and being able write it well and read it easily afterward is part of the joy of programming."

      --
      If other reasons we do lack, we swear no one will die when we attack
  39. shouldn't be coding... by Kalzus · · Score: 1

    Probably shouldn't. But possibly will be. And this hypothetical person won't be alone :(

    --
    "The Devil does not know a lot because He's the Devil, He knows a lot because he's old." -- unknown
  40. 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
  41. Please check your errors. by bill_mcgonigle · · Score: 1

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

    Please check your errors. I see far too many projects coded in Python that just barf stacktraces to the console if anything unexpected happens.

    Java has the advantage that it *makes* you handle your errors, even if you choose to do so poorly.

    --
    My God, it's Full of Source!
    OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
    1. Re:Please check your errors. by mkcmkc · · Score: 1

      Please check your errors. I see far too many projects coded in Python that just barf stacktraces to the console if anything unexpected happens.

      I'm not against error checking--I do it obsessively, myself. The issue I was addressing is what happens when errors are not checked, for whatever reason. In that scenario, which as we know is extremely common, the choice is between

      • a (somewhat) helpful error message followed by program termination, or
      • silently ignoring the error, likely resulting in invalid program behavior/output

      I believe that languages should fail safe because the former option is virtually always preferable. (And I have spent many hours debugging the fallout from the latter.)

      --
      "Not an actor, but he plays one on TV."
    2. Re:Please check your errors. by ClosedSource · · Score: 1

      "Java has the advantage that it *makes* you handle your errors, even if you choose to do so poorly."

      You must have a very weak definition of "handle". An empty catch block is not any kind of error handler, it's an exception hider.

    3. Re:Please check your errors. by bill_mcgonigle · · Score: 1

      You must have a very weak definition of "handle". An empty catch block is not any kind of error handler, it's an exception hider.

      As I said, you can chose to handle them poorly. But you can't chose to not handle them at all - something most languages let you do.

      It's like the shift interlock on a car - you can't take your keys out while it's still in Drive, but you can leave the keys in the ignition and abandon the car with it still in Drive.

      --
      My God, it's Full of Source!
      OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
    4. Re:Please check your errors. by ClosedSource · · Score: 1

      And as I said, merely satisfying the compiler isn't handling the error, poorly or otherwise.

    5. Re:Please check your errors. by bill_mcgonigle · · Score: 1

      And as I said, merely satisfying the compiler isn't handling the error, poorly or otherwise.

      So, if you want to be pedantic about it, then your problem is that Java lets you have an empty block instead of a non-empty block, right? I guess I would argue if you enforced a non-empty block a bad programmer would just System.out.println a useless message or call super's exception handler.

      --
      My God, it's Full of Source!
      OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
    6. Re:Please check your errors. by AuMatar · · Score: 1

      This isn't a language issue, its an IO library issue. A language does not do IO. A library does. Soemtimes these librarys are bundled with the language as part of a standard library, but there's still a huge difference. There's C++ libraries that handle IO just like you want. Its also possible to write a Python library that does the opposite.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    7. Re:Please check your errors. by ClosedSource · · Score: 1

      My problem is with the claim that Java forces you do handle errors, which it does not. I don't blame Sun for not being to solve this problem (nobody else has), but I do have a problem with misrepresentation.

    8. Re:Please check your errors. by bill_mcgonigle · · Score: 1

      OK, I see, we have a terminology disconnect.

      I was using definition 11 of handle and I think you're using definition 9. Some languages have specific constructs called 'handlers' but they don't have to actually handle anything if you don't tell them to.

      Perhaps the java 'catch' terminology is more precise then (though it's more definition 11 than definition 18 of catch).

      --
      My God, it's Full of Source!
      OUTSIDE_IP=$(dig +short my.ip @outsideip.net)
    9. Re:Please check your errors. by ClosedSource · · Score: 1

      I'm not sure I'd agree that your use matches either 11 or 9, but that's not really the point. Definitions of error "handling" that aren't relevant to the issue of making applications more robust I don't find very useful in comparing languages. The fact is that there's no compelling argument or real evidence that checked exceptions result in higher quality code than not using them.

    10. Re:Please check your errors. by mkcmkc · · Score: 1
      Okay. If you prefer, I'll say that this is how I want the default I/O library to behave. The important thing is that this is the behavior that the naive, untrained, or forgetful (read "human") programmer gets.

      Note that although I used I/O as my example, because it's such an important example, there are many other parts of the system that should probably work like this. See Python, for example, for other examples (consider the behavior of "int('foo')", for example). I'm sure there are other languages that do this, too, but I'm not sure which ones.

      --
      "Not an actor, but he plays one on TV."
    11. Re:Please check your errors. by achacha · · Score: 1

      Java also lets you re-throw a typed exception as untyped and then you don't have to every worry about handling it (which may confuse people using your code). catch(Exception e) { throw new RuntimeException(e); } etc.

      Saying that it's good that java forces you to handle typed exceptions is not always a good thing. Typed exceptions are nice for small programs but on large scale they are a pain.

    12. Re:Please check your errors. by Nevyn · · Score: 1

      There is also a third option, "program intentionally doesn't check I/O errors, as it's just informational text ... and is now broken, or contains copious except blocks in it". This is esp. important for certain types of I/O like "disk full" ... because they almost never happen, are easily checked by looking at close() (Ie. The C/POSIX idiom: if (close() != -1) rename();) when you have a normal language.

      Also IOError is also invisibly spewed by python if the file doesn't exist, which is often not even close to an "exceptional" event. So people often just introduce races into their python code by calling stat(), and then open if that succeeds, putting more spurious stack traces in front of the user. And if anyone wants to use open(foo, "r+") and get all their try/except blocks right ... good luck to them (but they'll be alone).

      James - Still waiting to experience one python app. that doesn't dump stack traces to the user at random corner cases, even the ones he's written :(.

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
  42. Some more tips by PaneerParantha · · Score: 1

    Several other tips may be added to those in the article. Some off the top of my head:
    1. Each parameter to a function on a different line, for example
    void foo(parm1,
                      parm2)
    {
          bar(parm1,
                  parm2,
                  parm3);
    }

    2. Put {} in an if stmt even if there's only one stmt. That is
    if(condition)
    {
          action();
    }
    instead of
    if(condition)
          action();

    3. Decouple
    Avoid (note the word is avoid, not don't at all)
    (stolen from a book, probably Writing Solid Code)
    if (pizza type is this)
    {
        bake this kind of pizza
    }
    else if(pizza type is that)
    {
        bake that kind of pizza
    }
    else if(pizza type is the other)
    {
        bake the other kind of pizza
    }

    Instead do this:
    if (pizza type is this)
    {
        create a pizza object of type this
    }
    else if(pizza type is that)
    {
        create a pizza object of type that
    }
    else if(pizza type is the other)
    {
        create a pizza object of type the other
    }

    pizzaObject.Bake();

    4. If you want to use stmts like
    if(5 == z)
    {
    }
    think whether you also want to carry them all the way to
    if(5 less than z) instead of if(z greater than 5) for the sake of consistency.

    IOW, decide what you want: consistency or ease of understanding in your code. Sometimes they aren't compatible.

    5. Always check boundary conditions.
    6. Always check arguments to functions for valid values.

    1. Re:Some more tips by Anonymous Coward · · Score: 0


      Instead do this:
      if (pizza type is this)
      {
              create a pizza object of type this
      }
      else if(pizza type is that)
      {
              create a pizza object of type that
      } ..
      pizza.bake

      all nice and dandy, but csc doesn't like this type of construct, even with if-then-else completeness.

    2. Re:Some more tips by BenoitRen · · Score: 1

      Instead do this: if (pizza type is this) { create a pizza object of type this } else if(pizza type is that) { create a pizza object of type that } else if(pizza type is the other) { create a pizza object of type the other } pizzaObject.Bake();

      I would use a switch there instead. Much clearer.

    3. Re:Some more tips by PaneerParantha · · Score: 1

      I would use a switch there instead. Much clearer

      True. However, and you may have figured it out as well, the intent was to demonstrate decoupling. Please comment on that part.

  43. please, check the code by eneville · · Score: 1

    Why does the author use code that won't compile in the documentation?

    Void change_score(short num_points)

    I totally agree with TIP #2 though, #define should not have been dropped from some modern C derivatives though.

    1. Re:please, check the code by Anonymous Coward · · Score: 0
      ..and just what's wrong with (syntax asside) using say:

      const int MAX_SCORE = 1048575;
      instead of

      #define MAX_SCORE 1048575
  44. Re:Use a language that checks I/O errors by defaul by Anonymous Coward · · Score: 0

    Its amazing how many people buy into this nonsense. I bet you think java stack traces are in any way useful to the end user as well? They must be a heck of a lot smarter than me cause I can't make heads or tails about what I should do as an end-user to address exceptions that are simply punted to the top.

    In reality just the opposite is true. By buying into exception handling and just expecting things to be handled by passing responsibility up the stack what you are really doing is loosing control and ownership the system along with the ability to systematically verify that *ALL* possible conditions are handled acceptably well.

    Its very easy to audit code and find all cases where return codes are not checked. Can you say the same for exceptions? How do you systematically know weather its ok for a particular exception to be punted or even what exceptions can possibly be generated by black boxes under you?

    In some areas this may very well be an acceptable response. However trading off programmer laziness for lower levels of reliability especially in server codes is a rediculous tradeoff.

    Using a language that ensures reasonable "islands of sanity" can be maintained (sections of code that can't fail unless the CPU does) is absolutly essential. Interpreted languages that do everything for you scare me sometimes however they are very useful for a wide range of purposes.

  45. Re:Use a language that checks I/O errors by defaul by cliveholloway · · Score: 1

    Perl has it.

    use Fatal qw(open close etc...);
    --
    -- Trinity in high heels carrying a whip: The donimatrix - there is no spoonerism
  46. Re:Use a language that checks I/O errors by defaul by CastrTroy · · Score: 1

    This relates to my biggest gripe about VB.Net. Any function can throw any exception, and you have no way of knowing, apart from looking at source code or documentation what kind of errors any specific function might throw. So basically all errors become runtime errors. This is one place where I wish VB.Net would copy from Java. If the function is going to throw an exception, it should be an compilation error if you aren't catching it. Also, related to this, when using ASP.Net, the debugger never breaks on uncaught exceptions, because effectively they are all caught at some level by the web server, so you have to break on all errors which causes a lot of wasted time as it breaks on internal errors in the .Net framework that are caught internally.

    --

    Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
  47. I've actually seen his code . . . by Anonymous Coward · · Score: 0

    Trust me, you don't want to see what it was like before he realized this (say ten years ago). We're talking numerical constants galore. Pages and pages with no comments, just string constants peppered here and there. Lotsa externs. At the same time, he made great games which I loved to play. There were some bugs, but it was pretty good overall, so who cares, right? It's debatable as to whether I'd have done any better at the time. :-) Ultimately it's a headache for him more than us, and I'm glad to see he's improved his practices. I hope he develops even more over time. Buy his games, they're fun and have a good storyline.

  48. const x #define by marcosdumay · · Score: 1

    "Wouldn't that be slightly less efficient?"

    No.

    "Wouldn't that allocate memory to hold the value rather than having a literal in the program code?"

    No.

    "Would be disaserterous if it caused a cache-miss too, you coul lose a lot of efficency there. Anyone know how various compilers handle const ints?"

    No, and you can't really know whre a cache miss will happen unless you know exactly what computer will run that code.

    Your compiler knows that a const is constant, and won't throw memory (and lookup time) away with it. Unless, of course, you want to debug. And you shouldn't be thinking about cache size while targeting the (quite heterogeneous) PC.

    1. Re:const x #define by ookabooka · · Score: 1

      Your compiler knows that a const is constant, and won't throw memory (and lookup time) away with it. Unless, of course, you want to debug. And you shouldn't be thinking about cache size while targeting the (quite heterogeneous) PC.

      Yeah I know that most cases it wouldn't matter, but I can think of quite a few worst-case scenarios with a lot of lookups. In any case, I know that you can modify const values by getting a pointer, casting to non-const, and then modifying it. But it appears that will only work if the value has already been allocated memory (such as parameter passing) or something. I tried manipulating a global variable in this manner and have gotten nothing but segfaults :) This is all in GCC btw.

      --
      If you are about to mod me down, keep in mind that this post was most likely sarcastic.
    2. Re:const x #define by EvanED · · Score: 1

      Yeah I know that most cases it wouldn't matter, but I can think of quite a few worst-case scenarios with a lot of lookups.

      You're not going to trigger any cache effects that matter because you use a const instead of #define.

      In any case, I know that you can modify const values by getting a pointer, casting to non-const, and then modifying it.

      If you want to provoke undefined behavior... "can" is too strong a word. You meant to say "may be able to in a non-portable and unreliable way".

    3. Re:const x #define by Anonymous Coward · · Score: 0

      You broke the #1 of debugging. You assumed you know how it works and did not look.

      99% of the time when I see a const being used it references the memory location not the constant. Compilers usually do not respect const. As you can cast it to non const and change the value. I have seen people do it.

      I can not tell you the number of times I have had someone say 'oh the compiler will optimize it'. Most compilers are not NEARLY as good at optimizing as the thing between your ears. You really give the optimizer way too much credit.

      SOMETIMES in special cases you will get what you are saying. But what if the const is in another file? What if it is in a header? Which of the 2 dozen versions of that const are you talking about?

      Also you are optimizing the wrong thing. If you had RTFA you would have noticed he said do not optimize too soon...

    4. Re:const x #define by frantzdb · · Score: 1

      99% of the time when I see a const being used it references the memory location not the constant. Compilers usually do not respect const. As you can cast it to non const and change the value. I have seen people do it.

      That depends. Any time you write to memory that should be const, you are in the land of undefined behavior. Consider this example:

      void muck_with(const int& x) {
        int& y = const_cast<int&>(x);
        ++y;
      }
       
      int main() {
        int x = 0;
        const int y = 0;
        muck_with(x);
        cout << "x now " << x << endl;
        muck_with(y);
        cout << "y now " << y << endl;
      }
      For me with GCC that outputs

      x now 1
      y now 0
      which is to say the constness wasn't completely cast away.
    5. Re:const x #define by marcosdumay · · Score: 1

      You happen to disagree with the wrong person. I happened to spend a few mounths studing GCC optimizations a couple of years ago because I was at a situation that required me to think about cache faults (and everything else).

      That means, I did look (but am assuming that the OP is using GCC). GCC doesn't spend memory with consts. And it is smart enough to know if you cast it to a non const (you can use -Wcast-qual to see it). Of course, if your program requires that the const is at memory (you use the operator & on it, or it is in an array), it will be. Oh, and you must use -O to get that optimization, GCC is quite conservative on its output.

      And, last, function paramaters are always at memory (unless you set the right optimizing flag), and you can always mess with them. You'd get the same behaviour with #define.

  49. Write comments first by sdaemon · · Score: 1

    When possible, the comments should be written before the code, describing the flow of data, the steps performed, etc. This helps not only the poor slob looking at the code months or years later trying to figure out wtf is going on, but also helps the initial author write the code correctly the first time, and debug it more efficiently the next two or three or sixteen times.

    In my years as a C coder, I found this to be a very helpful technique. It really helped me visualize what I was trying to do before doing it, and saved hours of debug time. And of course its always easier said than done, but it is a good goal to strive for.

  50. 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.
    1. Re:Two rules to live by by Anonymous Coward · · Score: 0

      ROTFL!!

    2. Re:Two rules to live by by Anonymous Coward · · Score: 0

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


      Awesome! Now if I only knew how to do this on purpose

  51. Comments are a code smell. by Anonymous Coward · · Score: 0

    Comments should be used in one situation and one situation only, and that's where a piece of code cannot be refactored to clearly reveal its intent witout resorting to comments. For everything else, refactor to reveal intent.

    Good example cases for comments are pieces of code that simply MUST do weird things that a developer wouldn't expect, often when dealing with crufty libraries that cannot be replaced and that require odd workarounds ala "// we have to call the open method twice because only a second call will completely open the connection". You simply cannot refactor around that kind of problem and as such a comment is the only option (short of replacing the underlying offending code.)

    Again: For everything else, refactor to reveal intent.

    1. Re:Comments are a code smell. by ClosedSource · · Score: 1

      If refactoring can reveal intent than either there's a lot more refactoring possibilities than I ever imagined or the set of possible intents is surprisingly small.

    2. Re:Comments are a code smell. by AuMatar · · Score: 1

      Not all intents can fit in a reasonably sized function name. English has one hell of a lot more expressive power than pidginCamelCaseNames. Refactoring can help, but its only one tool. Sometimes refactoring is better than comments, sometimes the other way. Not understanding the value of comments is a sign of a below average programmer.

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

    4. Re:Comments are a code smell. by Anonymous Coward · · Score: 1, Informative

      If a method doesn't convey intent well then it is too complex. If a commment is needed then it is a smell that says maybe the code should convey intent better. If you find out that breaking out something complex into intent-conveying methods leaves a lot of methods around then it is speaking to you that you might be doing too much in this class so look at your design. As an exercise, before you write a comment on WHAT a snippet of code is doing, see if you can make a method whose name is what the comment says. Of course, if you were practicing good TDD/TFD then you would most likely be refactoring little complexities as they come about which yields to naturally intent-revealing code.

      The only time I feel comments are useful is to comment on WHY the particular technique was chosen or the rationale behind why the particular approach was taken.

      2 cents

    5. Re:Comments are a code smell. by Bill+Dog · · Score: 1

      Not all intents can fit in a reasonably sized function name.

      Then the function is doing too much. A function should one thing. Refactor for higher cohesion.

      Comments are to be avoided unless absolutely necessary, for the same reason, for example, that you don't sprinkle the literal value of a buffer size throughout your code, you define it in one place, so that it's not even possible for things to get out of sync. The code is the authoritative set of documentation. A parallel set that low-level is an invitation to confusion after a period of maintenance. Not understanding the drawbacks of comments is a sign of a below average programmer.

      --
      Attention zealots and haters: 00100 00100
  52. 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
    1. Re:Tip 3 is crap. by PhxBlue · · Score: 1

      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.

      QFT. A better name might be ALIENS_ONSCREEN_MAX, to separate it from ALIENS_MAX (the total number of aliens stored in memory) and ALIENS_LEVEL_MAX (total number of aliens per game).

      I'm ambivalent on whether putting the word "number" (or an abbreviation thereof) in a variable name is wasteful. My realm of expertise is PL/SQL, which has strong types and won't let you perform character operations on numbers. How necessary is "ALIENS_LEVEL_MAX_NUM" versus "ALIENS_LEVEL_MAX" in a C++ application?

      --
      !#@%*)anks for hanging up the phone, dear.
    2. Re:Tip 3 is crap. by 2short · · Score: 1

      In a GOOD C++ app, you'll use

      const int ALIENS_LEVEL_MAX = 20;

      and get strong typing, scoping, namespaces, and various other goodies that come with letting your compiler in on what you're doing. Preprocessor defines are a stupid hack necessitated by the limitations of languages that went obsolete 20 years ago.

  53. The freshmen thank you? by Baavgai · · Score: 1

    These are ok for intro tips. Though if the goal is maintainable code I don't know if I'd be doing trivial stuff in C++.

    Saying use "#define" everywhere is pretty much like saying use globals everywhere. It's better than using constants, but sometimes not by much. Keeping variables scoped as tightly as possible can help save some pain; globals can add salt to the wound.

    1. Re:The freshmen thank you? by geekoid · · Score: 1

      Wow, you really, really do not understand #define, or the power they give the programmer.

      If you are using C or C++ and not using defines, I guarantee you your code is a disaster waiting to happen. Also, it's a maintenance nightmare.

      Sorry, but it's true.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    2. Re:The freshmen thank you? by drxenos · · Score: 1

      If you are using C++ and #define, I guarantee you that YOUR code is a disaster waiting to happen. DrX

      --


      Anonymous Cowards suck.
    3. Re:The freshmen thank you? by Anonymous Coward · · Score: 0

      You ever written multi-platform code?
      No? Ok.

    4. Re:The freshmen thank you? by drxenos · · Score: 1

      Of course. I write code that must run on a great many platforms, included custom-made embedded single board computers. Have for years. What's your point?

      --


      Anonymous Cowards suck.
    5. Re:The freshmen thank you? by geekoid · · Score: 1

      If you don't get my point, I don't ever want to see your code, because my comments on it would probably make you cry into your beard.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    6. Re:The freshmen thank you? by drxenos · · Score: 1

      I got your point. First off, it is quite easy to write multi-platform code without resorting to the preprocessor (though I don't have a major issue with people who do so). Second off, the article and the OP's comment were about using #define for constants in C++. It had nothing to do other uses (though they aren't necessary either). And I don't have a beard, nor do children and there comments make me cry.

      --


      Anonymous Cowards suck.
    7. Re:The freshmen thank you? by Anonymous Coward · · Score: 0

      Ever heard of const?

    8. Re:The freshmen thank you? by drxenos · · Score: 1

      Um, yeah. That's was my point: const should be using instead of #define in C++. Ever heard of reading? What's your point?

      --


      Anonymous Cowards suck.
  54. In the interest of full disclosure. by Allnighterking · · Score: 1

    Although java centric one must include information on how to write UNmaintainable code as well. The original unmaintainable code site (AFAIK)

    --

    I'm sorry, I'm to tired to be witty at the moment so this message will have to do.

  55. oh really? by geekoid · · Score: 1

    So your fine with assuming that the other developers variable names accurately show the intent of the function? Not me.

    And I will always take verbose over none.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    1. Re:oh really? by Anonymous Coward · · Score: 0

      So you're fine with assuming the text description relates in anyway to the actual code? Not me.

      I will always take the name of the function as a description of what it is supposed to do over none.

    2. Re:oh really? by mattoo · · Score: 1

      I guess if you can't trust others in your team to name their methods and variables correctly, you can't trust them to maintain their comments either. You're still stuck digging through code with inacurate variable names to know what it does, not being sure that the comments were changed along with the latest changes in the code.

      I think the while point is that you, as a team, write maintainable code and if you can adopt good principles when it comes to updating comments when the code changes, you'll probably also have enough discipline to name variables and methods correctly.

  56. Good ideas, bad execution by 91degrees · · Score: 1

    1. Commenting code makes sense. But the trick is to write the comments first. Then code.

    2. Don't use #define! It has file scope, and something like "#define SQUARE(x) x*x" will mess up if you give it "SQUARE(1+1)". Use const instead. Use functions insead of macros. The optimiser will inline simple stuff like that.

    3. Don't add redundancy to names. "MAX_NUM_ALIENS"? If it's a max it must be a number.

    4. It's more efficient to add the input testing code in debug only. You tend to have nice things like assert macros to help test as well.

    5. Don't be dogmatic about it. Just because Donald Knuth said it doesn't mean it's always true. Make sure your basic algorithms are efficient. You don't need a profiler to tell you that an array is going to be better for random access than a linked list.

    6. Quite true.

    1. Re:Good ideas, bad execution by tepples · · Score: 1

      Don't use #define! It has file scope, and something like "#define SQUARE(x) x*x" will mess up if you give it "SQUARE(1+1)". Use const instead. That doesn't always work in C, which won't let you use the value of a const object as the number of elements of an array.

      It's more efficient to add the input testing code in debug only. But then you have to be careful about which inputs are trusted and which are untrusted. Add sanity checking to a function even in the release build if there is a possibility that the function might be called with untrusted input.

      You don't need a profiler to tell you that an array is going to be better for random access than a linked list. And for efficient semi-random insertions, you can use a gap buffer, which is like java.util.ArrayList but better.
    2. Re:Good ideas, bad execution by David+Gould · · Score: 1

      2. Don't use #define! It has file scope, and something like "#define SQUARE(x) x*x" will mess up if you give it "SQUARE(1+1)". Use const instead. Use functions insead of macros. The optimiser will inline simple stuff like that. 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.

      Re. "#define SQUARE(x) x*x": that's why any decent style guide will include a rule like: "In the body of a parameterized macro, never ever ever refer to any of the parameters without using parentheses around it." "#define SQUARE(x) ((x)*(x))" is perfectly safe from that sort of problem. 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).

      You don't need a profiler to tell you that an array is going to be better for random access than a linked list. No, but you might need one to tell you whether or not this particular set is going to grow big enough for the difference to matter, or whether efficient insertion vs. efficient lookup matters more, etc. And you're very likely to need one to tell you whether or not a significant percentage of your total execution time is being spent in that piece of code. In my experience, he's right about this: profiler results are often surprising. The point is, they tell you what to optimize, not how to optimize.

      --
      David Gould
      main(i){putchar(340056100>>(i-1)*5&31|!!(i<6)<< 6)&&main(++i);}
    3. 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.

  57. Re:Use a language that checks I/O errors by defaul by Khashishi · · Score: 1

    Are you writing a quick tool or an application? For a quick tool, sure, you want a nice explanatory error message. But for an application, you might want to do something different. You might want to ignore the message or do your own error handling.

  58. Methinks Mr. Vogel doth protest too much. by starX · · Score: 1

    My favorite part is where he says: "if your C code requires you to know the difference between i++ and ++i, it is too complicated," because it makes me remember that being covered in my very first programming course, and that all code should perforce be understandable to someone who has finished maybe 1/3 semester of intro programming.

  59. Redundant? Not to some people. by Anonymous Coward · · Score: 0

    Especially the people I work with.
    What is the point in following any of the rules when no one else on the team does?

    "you deserve to have to maintain your own stuff 10 years from now."

    I've heard people say they explicitly _don't_ follow the rules so they _will_ be the ones who maintain it 10 years from now.

    "I've now had people from the support group stop me in the hall and compliment me."

    And I've had people stop and say: "Who gives a sh*t? I know what I'm doing, I have to maintain it. If I leave a mess, it's not MY problem."

  60. (JobSecImpt JobEaseImpt)?obfuscate():comment(); by zippthorne · · Score: 1

    But if you do do all this, you could be laid off and replaced with someone who'll maintain your code more cheaply.

    --
    Can you be Even More Awesome?!
  61. that and... by Anonymous Coward · · Score: 0

    ...it only takes one person on a team to not follow any of these guidelines to submarine the whole thing (if they aren't held accountable by management -- which all too often doesn't care).

    Everyone else starts to think "what is the point? Bob is not following the guidelines and he got the same raise I did last year, why bust my ass when all we need to do is make sure it works?"

    "Bob" doesn't care because he is the type who only cares that it works (or possibly not), and doesn't care if there is a mess because "I know the code; if I leave, it's not my problem anymore."

    The article isn't redundant because the % of "Bobs" is high.

    1. Re:that and... by mstahl · · Score: 1

      "Bob" doesn't care because he is the type who only cares that it works (or possibly not), and doesn't care if there is a mess because "I know the code; if I leave, it's not my problem anymore."

      In the biz, we call that the "job protection" coding paradigm.

  62. Not true by Anonymous Coward · · Score: 0

    The behaviour of the code is not implementation dependent. It's actually undefined. (The C standard makes a huge distinction between the two types of behaviour). Not only is a C compiler allowed to return one of the 24 possibilities you thought of, but it's also allowed to return ALL 24 of them, go back in time, return another 9 that are physically impossible, have sex with your mother, and start World War 3 as a side effect. There is no limit on what can happen when you invoke undefined behaviour. Beware the wrath of standard C.

    1. Re:Not true by harry666t · · Score: 1

      You made me lmao :P actually 'g++ -o a.out this.cc && ./a.out' outputs '1-337' on my machine, but I really didn't test that with anything else.

      Damn, I'd mod you +8 funny but I already posted a comment...

  63. I'm a compulsive commenter. by Mr+Z · · Score: 1

    And it's saved me and others countless time, I'm certain. When it comes to C code I comment similarly to how the article suggests. It's fairly obvious. For example, consider this code. There's some tricky stuff involved in correctly emulating the controller inputs for the Intellivision, and the bulk of the comments revolve around explaining the trickiness.

    That said, when I code assembly language, I tend to comment nearly every line. Why? Unlike C code, most assembly statements aren't very descriptive. For instance, "MVI@ R4, R0" means "read whatever R4 points to into R0." Ok, but what might R4 be pointing to? What kind of thing are you reading? What are you trying to accomplish? Imagine if you wrote your C code so that all pointers were named p and q, and all other variables were named i, j, k, a, b, and c. That's what assembly's often like. So, I use short per-line comments (or sometimes per group-of-lines comments) to add that missing information. Here's an example from Space Patrol. (In this particular example I also was counting cycles, due to the performance critical nature of the code. That's an entirely different story.)

    All I can say is that comments like these have saved my ass more than once.

    --Joe
    1. Re:I'm a compulsive commenter. by daverabbitz · · Score: 1

      All I can say is that if your assembler looks like that, you're not using auto-registers and macro's properly. Now I'm a little rusty, and I can't think of a particular assembler that I've used recently, but:

      #define total r1
      #define item_value r2
      #define items r3
      #define count r4

      sum:
      mov item_value, @items
      addd items, -4
      addd total, item_value
      decd count
      cmp count
      jnz sum

      Reads better than: .offset 0x6860686
      mov r2, @r3
      addd r3, -4
      addd r1, r2
      decd r4
      cmp r4
      jnz 0x6860686

      (Note this isn't any particular assembler for any particular architechture, but I'm sure you can get the gist of what it does).

      --
      What could be better than a jet powered motorcycle? http://www.youtube.com/watch?v=u8l6GTHLSWE
    2. Re:I'm a compulsive commenter. by daverabbitz · · Score: 1

      For the record:

      I didn't mean to imply that comments are bad, just that using sensible names in assembler is just as important as any other language.

      --
      What could be better than a jet powered motorcycle? http://www.youtube.com/watch?v=u8l6GTHLSWE
    3. Re:I'm a compulsive commenter. by Mr+Z · · Score: 1

      Oh, believe me, on more capable assemblers for larger architectures, I do that sort of thing. I use symbolic names when possible. Here's a dot product kernel more along the lines of what I write when I'm writing for a "big" machine.

      For this tiny, ancient machine, the assembler is a hold-over from 16-bit DOS. You could almost call it a toy assembler. There are only 6 general purpose registers, and they're not *quite* general purpose. Shift instructions only work with R0-R3, indirect addressing only works on R1 - R5, with R4 and R5 auto-incrementing. JSR return addresses can only go in R4, R5 or R6. (I don't count R6 as a general purpose register as it is the stack pointer, though most instructions can operate on it.)

      My point is, for a tiny machine, it only works against you to name your registers symbolically. Imagine doing this for the 6502, which has one accumulator, A, and two index registers, X and Y. In fact, the register name is built into the opcode.

      Oh, and I do use labels. I don't hard-code offsets unless it's called for. :-P

      --Joe
  64. I'm a true believer by Thaelon · · Score: 1

    Having been a part of a mostly support team (read: virtually no new development) for the past year and a half I can tell you that each extra minute you spend tweaking those variable names into something meaningful, encapsulating logic into methods, writing good comments that are meaningful to someone who's never seen the code before - and generally, writing good, commented code will save you man-months in the future.

    I can't emphasize this strongly enough. Spend the time right now to write it so damn well you never have to see it again, or waste man-weeks fixing it later.

    If it's short and terse, it's fucking wrong.
    If it's clever and creative, it's fucking wrong.
    If it's convenient and "more compact" to write it all on one with ternaries or lots of nested or chained operations on one line rather than a method, it's fucking wrong.

    They say that brevity is the soul of wit. But in code, brevity is the soul of insanity.

    Write it well the first time and subsequent changes are easy. Writing it poorly the first time leads to buildings full of maintenance programmers. You don't want your code to be that bad do you?

    --

    Question everything

  65. The KISS Principle by Prototerm · · Score: 1

    And no, it's not about wearing face paint when you're coding, smartalec! It's "Keep It Simple, Stupid!"

    While a lot of the points in the article are painfully obvious (note however several people here criticizing the use of any comments in code. Arrrgh!), the last one covers my biggest gripe when fixing someone else's code. I call it "Gee, Mom, look what I can do" code. Spare me, please, the people who code to impress. And it's not just C and C++ that are susceptible to this (my particular "favorite" is crap like "if(a=14)". It's wrong on so many levels, even if it does work as intended -- note the single equal sign instead of a double one). Object Pascal, Basic, every language I've worked with has its own delightful way of letting you obfuscate the hell out of things, and shooting the *next* guy in the foot. Even raw assembler has a nice trick or two up its sleeve (anyone remember unimplemented opcodes?).

    The only thing that impresses me is code that is simple (no huge, miles-long functions that run hundreds or thousands of lines), obvious, and works.

    --
    "My country, right or wrong; if right, to be kept right; and if wrong, to be set right." --Senator Carl Schurz (1872)
  66. Re:Use a language that checks I/O errors by defaul by Josef+Meixner · · Score: 1

    Where have you learnt C++? If you use iostream you can set them to throw exceptions: Exception Mask. It isn't done by default, because a failing IO-operation is hardly a big surprise (incorrect rights, nonexisiting file, out of data). I find exceptions overrated, they make it awkward to check the state and should be reserved where you really need to unwind the stack not for simple state checks.

  67. Simple really by riskeetee · · Score: 2, Funny

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

  68. *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?

  69. Rules for incompetent coders by hesiod · · Score: 1

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

    WTF??? If you don't know the difference between i++ and ++i you have no damn business messing with my code!

    1. Re:Rules for incompetent coders by PhxBlue · · Score: 1

      WTF??? If you don't know the difference between i++ and ++i you have no damn business messing with my code!

      It's easy to know the difference. It's also easy to overlook them both when you're trying to find out what's causing a bug.

      i++ works. So does i = i + 1, but the latter is self-documenting. Either way, be consistent ... if you're a ++i type of person, don't put i++ in your code, and vice-versa. That reduces one level of possible error from the process later on for the person who has to maintain your code after you've retired or moved on.

      --
      !#@%*)anks for hanging up the phone, dear.
    2. Re:Rules for incompetent coders by EvanED · · Score: 1
      The point isn't that you know the difference, the point is that if you have to think about the difference your code could probably be improved by splitting it.

      Why is

      *p++ = *q++;
      better than

      *p = *q;
      p++;
      q++;
      ?

      Answer: unless for some reason you are coding on a screen that only shows you 3 lines of text at once, it isn't.

      Why make the programmer (i.e. you in a couple weeks) think harder about what the code does then you need to?

      loqi said it best: "Expressions are like sex: they're better without side-effects."
    3. Re:Rules for incompetent coders by geekoid · · Score: 1

      If tyou don't know why that can be a nightmare, I don't want to see your code!

      FYI, unless you write your own programs for your own company, it's not your damn code.

      What is it with this industry and their compulsive 'it's MY code you can touch it syndrome'?

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  70. The writer knew it was obvious and stated so by geek2k5 · · Score: 1

    The second to the last paragraph of the article touches on the fact that it is obvious. And that paragraph expressed the hope that people were thinking that when they were reading the article.


    The last paragraph mentioned that methods of writing maintainable code that may be obvious to you may not be obvious to everybody.


    People get into programming through many routes and encounter many programming standards (or lack of them). They also, over time, change how they do things, especially when encountering unreasonable deadlines and corporate standards. Having occasional reminders of good programming practices helps.


    Note that the 'References' section of the article has links to other tips on writing maintainable code.


  71. That is so wrong. by lilomar · · Score: 1

    I mean, someone should at least talk to ken and see if he is still a jackass, and reset the bool accordingly.

    --
    The creator of this post (Jacob Smith) hereby releases it, and all of his other posts, into the public domain.
  72. Whipping a dead horse? by east+coast · · Score: 0, Flamebait

    Disclaimer: I have not RTA.

    From the blurb: one minute spent writing comments can save you an hour of anguish

    Ummm... Ok. We've seen this tidbit of good advice over and over again. Why is it that we keep pounding away at it? From where I sit, good coders will have good coding practices without having to have it tattooed into their foreheads. A good coder takes interest in being (tada!) a good coder. People who need these type of simple coding tips beat into their heads are not interested in being good coders. It's that simple yet we see it repeated again and again.

    Maybe we just need bad coders to be kicked to the curb. There are plenty of us who are willing to follow the basic standards of good coding because we want our code to be understandable by others. We don't see commenting code as drudgery. We don't need it beaten into us.

    Let the deadwood go, for once and for all.

    I know it seems like a rant but I'm always looking for these good coding practices articles and they all end up saying the same 6 or 8 things. It's becoming as tedious as reading some gaming sites top 10 FPSs... again. We know everyone loves UT and HalfLife. Enough already!

    --
    Dedicated Cthulhu Cultist since 4523 BC.
    1. Re:Whipping a dead horse? by geekoid · · Score: 1

      TO become a good coder, inexperienced and/or bad coder need this lesson repeated to them many, many times. That's great that it doesn't apply to you, but there are people who need to hear it again, and again, over and over. A lot of people if the posts no /. are an indicator.

      Was that last sentence grammatically correct?

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    2. Re:Whipping a dead horse? by Anonymous Coward · · Score: 0

      Ok. We've seen this tidbit of good advice over and over again. Why is it that we keep pounding away at it?

      Well, for one thing, it wasn't always taught this way. When I took my C and Pascal and Assembler courses back in the Mesozoic Era, the books and instructor said, "Good, clear code doesn't need comments." So there were a lot of folks who thought their code was perfectly lucid.. Until six months later when they had to maintain it. Then that advice didn't seem so good.

      There are lots of other things too. There are optimization methods that no longer are useful with current CPUs. There are coding practices that, though clever and acceptable at one time, are now bad practice. Heck, even comments in some early languages could cause CPU issues. Think that's just an old problem? Well, it's not unusual to have comments stripped from web pages because the extra bytes are extra bandwidth. But some programmers do this before committing code now.

  73. Re:Use a language that checks I/O errors by defaul by EvanED · · Score: 1

    It isn't done by default, because a failing IO-operation is hardly a big surprise...

    Well, not really... it isn't done by default because the original iostream library was created before exceptions were added to C++, and changing the interface would have broken legacy code.

  74. Restating the 'obvious' by geek2k5 · · Score: 1

    What is obvious to you may not be obvious to everybody. And the author admits that in the last two paragraphs.

    Note that 'everybody' may know it but not everybody may practice it. Also note that not all organizations train people the same way. There are still those people who come up through the ranks and are not formally trained.

  75. haha by geekoid · · Score: 1

    no, I've been coding for a whikle and apparently only I know this..grumble stupid old code...stupid cantractor..grumble grumble.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  76. 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.

    1. Re:Simple Enough by the_greywolf · · Score: 1

      Indeed, but I wouldn't mind being the guy that had his games stolen from him.

      --
      grey wolf
      LET FORTRAN DIE!
  77. Re:Use a language that checks I/O errors by defaul by arevos · · Score: 1

    Every time you create something, destroy it afterwards. Assume every action will fail and handle it appropriately. Your advice applies well to C, but since the parent poster was talking about Python, your advice is not actually that good. It's bad practise to explicitly delete objects in Python, and typically you'll want to hang off on handling exceptions until you get to a suitably high level. But I'll grant that's it's a good idea to make liberal use of the finally keyword when dealing with I/O :)
  78. 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.

    1. Re:Hungarian Notation by Anonymous Coward · · Score: 0

      Total BS. It has nothing to do with development.

      In maintenance, you want to be able to look at the code and tell what type a variable is supposed to be without having to refer to the definition, without having to load up an IDE, and often enough without even having to have the project in a compilable state.

    2. Re:Hungarian Notation by Anonymous Coward · · Score: 0

      Huzzah for Java. :P

      I think the debate regarding Static/Strong/Dynamic typing relates to this. Comparing, say, Java and PHP (or Python)... The former is a lot easier to maintain when you want to know what data type is coming back at you.

    3. Re:Hungarian Notation by ClosedSource · · Score: 1

      One would hope that most variables of types covered by HN (i.e. basic types, not classes) would be used within a short distance of their definition assuming modules/classes are of reasonable size and the application isn't using many global variables.

      In practice, I don't think the lack of HN is going to have much impact on maintenance efforts. You should also consider that the HN name may be wrong, so you can't be sure of the type just by looking at the name.

      The biggest problem with HN is the coupling of names and types. The most famous example is probably Windows Message parameters. In 16 bit Windows there were 2 types of parameters you could pass in a message: WPARAM which was properly named because it was a 16 bit value and LPARAM which was a 32 bit value.

      When Windows was upgraded to 32 bits, all native types were 32 bits in size, so the "W" in WPARAM was superfluous and the "L" in LPARAM was incorrect. Rather than update all of their code and documentation to make it HN compliant they wisely decided to ignore the issue and live with inconsistent names.

    4. Re:Hungarian Notation by igomaniac · · Score: 1

      Where I work, we use a naming convention similar to Hungarian, but the goal is a little different -- the point is to _enrich_ the C type system, so we use iVertex where the 'i' indicates it's an index (into an array) and nVertices where it's a number (the number of vertices in said array). We also separate between pVertex and paVertex to indicate if a pointer is to a single vertex or an array of vertices. Several other prefixes are also used to indicate for example that an int is really a bitfield 'b'.

      --

      The interactive way to Go -- http://www.playgo.to/iwtg/en/
  79. Re:Use a language that checks I/O errors by defaul by mkcmkc · · Score: 1
    Thanks for the link--I had a vague notion that C++ iostreams could do something like this, but hadn't seen an example.

    Unfortunately, this doesn't address the problem I was speaking of, for two reasons:

    1. It isn't enabled by default (so it won't help naive programmers), and
    2. the default error message--meaning "what gets printed if the exception isn't caught"--isn't sufficiently useful, at least for g++ 4.0. So, for example, if you try to open a nonexistent file, the message doesn't say that, nor name the file:

      terminate called after throwing an instance of 'std::ios_base::failure'
      what(): basic_ios::clear
      Aborted

    Still, if this were enabled by default, it'd be an improvement.

    --
    "Not an actor, but he plays one on TV."
  80. 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.

  81. 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."
  82. Programming 201 by geek2k5 · · Score: 1

    Structured coding would be for the more advanced programmers, especially in organizations that use it.

    Some organizations don't have the support needed for structured coding and related practices. They often have legacy code that works and just needs tweaked to handle new conditions. Applying structured code would often require rewriting large parts of applications that may have been running for decades.

    Of course, structured code could be brought in for the handful of 'clean sheet' projects that sometimes appear. And it could come into play IF the IT staff can convince the bean counters that a critical application needs to be rewritten to be more efficient and provide enhanced abilities.

  83. bullshit. by Anonymous Coward · · Score: 0

    *p++ = a;
    *p++ = b;
    *p++ = c;

    vs.

    *p = a;
    p++;
    *p = b;
    p++;
    *p = c;
    p++;

    The former is idiomatic use, the latter what a VB coder would do.

    1. Re:bullshit. by Anonymous Coward · · Score: 0

      I think I agree that the *p++=a; is the wrong way to do it.

      Yes, anyone should be able to read it, but it masks the actual operation.
      You really are setting the next 3 positions of p to a,b and c respectively and advancing p 3 positions.
      Is there any reason a,b,c are separate variables? Perhaps you'd have been better off putting them in an array and memcopying it into place.
      Is p just a copy of the real pointer or might something else expect to it to not change?

      Breaking it into simpler pieces not only makes it easier to see what the end result is, but helps you find inefficiencies and off by 1 errors more easily

    2. Re:bullshit. by Anonymous Coward · · Score: 0

      You really are setting the next 3 positions of p to a,b and c respectively and advancing p 3 positions. Actually, I'm appending three items to a list and this is the clearest way to express that to an experienced C programmer. It's like "add(a); add(b); add(c);".
      If I were to do something with the list between adding a and b I'd just put it between them. If I think I don't need to add b after all, I'll just remove the line. etc.

      Had I written "p[0] = a; p[1] = b; p[2] = c; p += 3;" these actions would require little more (and thus would be more bug-prone).

      However, as always you need to know when to use this idiom. If you were writing a file header, you'd probably better spell out indices directly. (let's see, what I am writing to position 54 again?)

      Is there any reason a,b,c are separate variables? Perhaps you'd have been better off putting them in an array and memcopying it into place. Sigh. Perhaps I should have used traditional metasyntactic names to emphasize the placeholderish nature.
    3. Re:bullshit. by loqi · · Score: 1

      *p++ = a;
      *p++ = b;
      *p++ = c;

      If line-breaks burn your eyes so much, then:
      *p = a; ++p;
      *p = b; ++p;
      *p = c; ++p;

      This occupies roughly the same amount of screen-space and logically separates the dereferencing of the iterator from its modification. Furthermore, if this is C++ and you're writing generic code, mine is potentially faster if the iterator's post-increment requires too much data movement and/or the compiler can't fully optimize it away.

      --
      If other reasons we do lack, we swear no one will die when we attack
  84. Re:Use a language that checks I/O errors by defaul by mkcmkc · · Score: 1

    Looks good--I wish it were enabled by default.

    --
    "Not an actor, but he plays one on TV."
  85. VERY good points by geek2k5 · · Score: 1

    These points should be drilled into everybody who is learning how to program with an eye to doing it professinally. While the effort to do things right may seem like a waste of time now, it will prove invaluable later. (They may also want to improve their command of the English language so that the documentation is understandable, at least in those places where English is the language of choice.)

    My biggest complaint about programming and software development classes is that they tend to focus on what I call 'clean sheet' programming. You start with nothing and end up with a series of programs that meet the needs of the class. The documentation you put in the programs meets the requirements of the teacher as specified in the class requirements. Then you put the programs aside and never revisit them again.

    Unfortunately, the real world isn't like this. There are legions of SUPPORT programmers that will eventually have to maintain 'clean sheet' programs.

    With this in mind, I would challenge any educational organization to have classes on how to do SUPPORT programming, especially for poor code. The students would NOT be permitted to rewrite things unless they can guarantee that EVERYTHING would still work after it is rewritten. And the results would need to have better documentation than the original.

    Would be programmers might learn to do things right after experiencing what happens when they are done wrong. Or they might decide that accounting or truck driving is a better profession.

  86. 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 geek2k5 · · Score: 1

      I loved the article and marvel at the number of people who apparently didn't read it all the way through. While it is basic, it also covers things that not all experienced programers do on a regular basis.

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

    3. Re:A Note From the Author by mauddib~ · · Score: 1

      What I'm missing in your article are more important things, such as:

      * Modularization
      * Adaptability for future changes
      * Code structuring (ie. preventing hairy code)
      * Version control
      * Writing self-documenting code
      * Function/procedure pre- and post-conditions and change of state
      * ... (list goes on)

      But then again, that's probably not the intended audience for IBM, would it be?

      --
      This is a replacement signature.
    4. Re:A Note From the Author by iggy_mon · · Score: 1
      not to patronize you, but thanks!

      i've been learning c++ on my own for a while (i got stuck on the concept of pointers, recently resolved(!)) but i thought your article was very helpful to me (again, a complete rookie). i especially appreciated tip number 5 (Premature optimization is the root of all evil). i've found myself wondering if what i'd written was "the best way possible" instead of "will it (even!) run".

      anyways, don't let the slashdot flamebaiters get to you. you set out to write for a rookie and you succeeded.

      btw: "It's worth a visit to see just how much damage you can do with an encyclopedic knowledge of a programming language, combined with a lack of shame." cracked me up! :-)

      --
      --iggy_mon - www.ananonymouskiller.com - Die Trying -
    5. Re:A Note From the Author by bryan1945 · · Score: 1

      What part of-

      "It's an introductory article. It's sold as an introductory article. "

      did you not understand?

      --
      Vote monkeys into Congress. They are cheaper and more trustworthy.
    6. Re:A Note From the Author by Stormie · · Score: 1

      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.
      Of course. But it's really not helpful to teach people poor practices with which to implement good concepts. Can you just fix the bit about #define constants up and reupload the article?
    7. Re:A Note From the Author by Glorat · · Score: 1

      Slightly OTT but I just had to say something in support...

      Avernum 3 was one of the best games I ever bought. Thanks!! /Fan

    8. Re:A Note From the Author by iwein · · Score: 1

      I hope nobody said this already: Man! you're not helping the inexperienced programmer keep his job!
      http://www.thc.org/root/phun/unmaintain.html/ is the way to go.

      Of course you're right and even if it is obvious there is no harm in reading it and thinking about it for anybody. This is slashdot, you _will_ be stabbed at if you say something ;)

      --
      Show a man some news, distract him for an hour. Show a man some mod points, distract him for the rest of his life.
    9. Re:A Note From the Author by mauddib~ · · Score: 1

      I guess the part 'it is sold as...'. It is my sincere belief that in order to correctly program, it is important to regard structure as the most important feat of any successful implementation. Comments often appear out of a lack of structure, either because the programming language is not expressive enough, or the programmer does not know the expressiveness of the programming language itself. Therefor, in order to write correct comments, it is important to first focus on the logic language and its abilities, before trying to explain things in an ambiguous natural language. Lastly, I would like to stress that natural language has much more peculiarities than a computer language, and in order to write good comments, it should be mastered as well as the logic language.

      But, yes, 'it is sold as...', seems to cover this general inconvenience under the mom of: they are not bright enough to understand. What a load of bullshit, and the worst thing is that I'm afraid I'm in a career that will someday ask the same of me.

      --
      This is a replacement signature.
  87. Rule number one? by Anonymous Coward · · Score: 0

    Don't write meaningless comments into your code, but instead share them with us.

  88. Also green by ChefInnocent · · Score: 1

    What is also green are those people who think they should const or #define sequential sets. Use enum folks! Enums allow you to auto-increment/decrement your set, or re-order without having to re-type a bunch of numbers. Also, it doesn't hurt to add an end reference to your set for future use, eg:
    enum EFruits {APPLES = 0, BANANAS, CLAMENTINES, DURIAN, EGGPLANT, GUAVA, ELAST_FRUIT};

    Then later in your code you can run over the enumeration as follows:
    int dxFruit;
    for(dxFruit = 0; dxFruit ELAST_FRUIT; dxFruit++)
    { // Do something.
    }

    The advantages are if you go back and add FIGS to the list, you don't have to hunt down every instance you ever used the fruit set to ensure your count is right, and you don't have to re-number GUAVA. I really hate seeing:
    #define APPLES 1
    #define BANANAS 2
    #define CLAMENTINES 3
    #define DURIAN 4
    #define EGGPLANT 5
    #define GUAVA 6 ...
    for(i = 0; i 7; i++)
    { // Do something.
    }

    Another advantage is to eliminate the referencing of "magic numbers". I just want to flog the person who write:
    if (myFruit == 3)
    {
    }

    I shouldn't have to spent a fortnight looking up what the hell 3 means!

    1. Re:Also green by Breakfast+Pants · · Score: 1

      Shouldn't that be:

      for(dxFruit = 0; dxFruit != ELAST_FRUIT; dxFruit++)

      --

      --

      WHO ATE MY BREAKFAST PANTS?
    2. Re:Also green by Bill+Dog · · Score: 1

      You should probably use const's for things where the particular values of the items are important or meaningful. While the values of enumeration constants can be specified, it's not really in the spirit of enums. That is, if you have an enum Color, and constants eRed, eBlue, and eGreen, their usage should not depend on the particular numeric values the compiler or you assign to them. They should be used as the abstraction, not the underlying representation.

      So, if I really needed to iterate over all my fruit:

      enum Fruit
      {
              eBegin,
              eApple = eBegin,
              ePear,
              eOrange,
              eEnd
      };

      for ( Fruit fruit = eBegin; fruit != eEnd; fruit = static_cast< Fruit >( fruit + 1 ) )
      {
      // do something
      }

      The only time I use enums' integer values is when I on occasion use them for bit masks:

      enum FileProperties
      {
              eReadOnly = 1,
              eSystem = 2,
              eHidden = 4,
              eDirectory = 8,
              eSpecial = 16
      };

      --
      Attention zealots and haters: 00100 00100
  89. Developers in training by geek2k5 · · Score: 1

    Does Slashdot have a section for developers in training? If so, then the article should be there. If not, then having it here is useful for the newbies.

    Heck, having it available as a reminder for the experienced developers makes it worth having here. People can get sloppy over time.

    Of course, there are developers that are not well trained in certain areas. They may be able to crank out highly functional code ten times as fast as everybody else, but the maintenance cost of that code may be sky high. That is where these articles can come in handy IF the person is willing to learn.

    Do you know any 'super programmer' whose code requires another 'super programmer' to understand, much less maintain? They may be the one that needs to see this article. (And they may also be the one least likely to view it.)

  90. Re:Use a language that checks I/O errors by defaul by ClosedSource · · Score: 1

    Perhaps the compiler should force you to write a short summary of each function's purpose, parameters, and return type. Otherwise you have no way of knowing, apart from looking at source code or documentation, what the function might do.

    Seriously, if a compiler were capable of informing you that you haven't handled an exception properly, that would be great, but that's not what Java does. It merely looks to see if you appear to be handling it or that you've passed it up the call chain. For most GUI applications, 90% of the exceptions should be handled at the "top", so you have to add boiler-plate code all over the place to keep the compiler happy. Then if Sun adds or removes an exception from an existing library, all the code that is in the call chain is broken.

  91. If you're going to lecture on basics... by mike260 · · Score: 1
    ...then you should make some effort to get them right.

    Tip 2: Use #define a lot. No, a LOT.
    Hmm, I thought consts were more the C++ way. Debuggers and IDEs are much better at keeping track of them, which makes life much easier.

    // 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.
    Why is this function's comment describing an ENTIRELY DIFFERENT PIECE OF CODE? It should describe the function itself, NOT it's caller.
    It's also very likely wrong, since the function will almost certainly be called (NUM_BULLET_MOVES_PER_SECOND*num_active_bullets) each second.

    Return is_destroyed;
    This doesn't compile (unless you've done something stupid with the preprocessor). Lesson: Don't use winword to write C++.

    Void change_score(short num_points)
    {
    if (num_points < 0)
    {
    // maybe some error message
    return;
    }
    Again with the editing code with a word-processor! It's 'void', not 'Void'.
    And you think that in the event that num points is -ve you should MAYBE throw up an error? Seriously? Because it's a bug in the caller and not the function, it's not the function's problem right? So it's best to ignore it right?
    And what's with all the shorts? You realise that shorts suck on every x86 since the PPro, right? I could understand using them in a size-critical struct, but as loop counters? Bizarre.

    Teaching the basics is great, I'm all for it. But this article stinks.

  92. A comment on Comments by iandykes · · Score: 1

    Most of the arguments for in depth comments are actually tell tale signs that code needs to be refactored. I don't think this article gives too good examples on how to comment you code, and it seems the author doesn't have too much experience in team programming with a fluid code base.

    Some code will always require a comment, but if you can write code that doesn't require one, then IMO that's better than masking unnecessary code complexities with comments.

  93. The author could stand to read his own article... by SanityInAnarchy · · Score: 1
    Example from TFA: // move all the aliens
    for (short i = 0; I < MAX_NUM_ALIENS; i++)
            if (aliens[i].exists()) // this alien currently exist?
                    aliens[i].move_it();


    I realize that for the game he's currently got, a short may be sufficient. But it's not hard to imagine a later version supporting swarms of aliens, with individually animated tentacles (each of which might count as an alien in that array), etc etc.

    Personally, when dealing with code written in a statically typed language, I like to make sure I #define every single type I'm using, even if it's something simple like a short, because you never know when you'll have to change it. Probably makes it easier to go 64-bit clean, too, but in any case, it's something I learned from the Linux kernel, and it seems to just make a lot of sense.

    He also didn't seem to be using a particularly object-oriented style, for a so-called C++ programmer:

    Void change_score(short num_points)
    {
            score += num_points;

    make_sparkles_on_score();
    }


    As others have pointed out, that's a damned weird coding style. But whatever.

    The point is, as he says:

    The problem here is that we probably don't want the scoreboard to flash with pretty colors when the number displayed doesn't change.
    And of course, what he's likely missing here is, we probably don't want the score to ever be updated without making the screen flash with pretty colors, either. So where is that function? Looks global, but it's been awhile since I've done C++. But if it is global, that implies that something else, somewhere else, might update the score for no apparent reason, and neglect to call make_sparkles_on_score().

    And also: What else might we want to do with the score? Is the score the only thing we want to display and change, anyway? (Maybe we want to implement health later, or some other statistic that should be up there and flash some animation when updated.)

    It seems to me, the obvious thing to do here is create a class for score, and override the relevant mathematical operators. (One of the few legitimate uses for operator overloading, but I digress...) Maybe it's just me, but saying change_score(10) seems a lot less intuitive than score+=10.

    It would also solve the problem of that explicit short. I don't suppose anyone would ever want to change the score by more than 65,535? Wait, it's a signed short, so half that. ...And why is he accepting a signed short, and then checking whether it's positive? (And why even care whether the score goes up or down, on that level -- I don't think it's the job of the score change itself to do that check, you'd do that after any calculation where you want to make sure it's a positive change in score.)

    I admit some of these are a matter of taste -- some people don't like object-oriented programming. But I do think some of them are fairly obvious, almost instinctive for me.
    --
    Don't thank God, thank a doctor!
  94. Mext up on Slashdot! by r_jensen11 · · Score: 1

    Six ways to create proper spread sheets!

    Step 1: Color-code
    Step 2: Reference other cells for static numbers in functions
    ???
    Profit!

  95. It needs a proofreader by trolltalk.com · · Score: 1

    FTFA: // move all the aliens
    for (short i = 0; I MAX_NUM_ALIENS; i++)
            if (aliens[i].exists()) // this alien currently exist?
                    aliens[i].move_it();

    Note that this is an infinite loop.

    Should be "i MAX_NUM_ALIENS;", not "I MAX_NUM_ALIENS;"

    1. Re:It needs a proofreader by trolltalk.com · · Score: 1

      And slashcode needs its "plain-text post mode" fixed. It STILL eats < and > in PLAIN TEXT!!! Come on guys - this bug has been around for YEARS. (I guess they'll fix it around the time they fix the b0rked nested view when there are too many comments ... in other words, not in your lifetime!!!)

      FTFA: // move all the aliens
      for (short i = 0; I < MAX_NUM_ALIENS; i++)
                      if (aliens[i].exists()) // this alien currently exist?
                                      aliens[i].move_it();

      Note that this is an infinite loop.

      Should be "i < MAX_NUM_ALIENS;", not "I <MAX_NUM_ALIENS;"
      I MAX_NUM_ALIENS;

    2. Re:It needs a proofreader by achacha · · Score: 1

      should also be:

      for (short i; i < MAX_NUM_ALIENS; ++i) ...

      This way if 'i' changes from short to something a bit more complex you don't create a duplicate object when you do a post increment (thanks for Scott Mayers for that one).

  96. Re:Use a language that checks I/O errors by defaul by mrvan · · Score: 1

    I don't want to be annoying, but: error handling is for handling errors, and finally is for finalization whatever else happened.

    ie if something needed cleaning up, I trust a finally clause way more than any if (h_res==0) {clean;} I can ever write, and if it is handleable (is that e really necessary), well, handle it in the catch clause!

  97. Don't write comments, don't read comments by z-j-y · · Score: 1

    if you are a writer, write simple, stupid, clear, short, structured, descriptive, idiomatic codes

    if you are a reader, read the code. if the code is a piece of crap to read, its comments are more likely so.

    if you are a PM/architect or whatever your company calls those useless nannies, please, either your men are too stupid and none of your beautiful processes will change that, or your men are a little bit more intelligent than you and all your crappy cliches are nothing but insults

    the title and the first two points are figuratively speaking, people with common sense will get it.

  98. Some others I've found... by benow · · Score: 1
    - use a good ide: easier to build on codebase, easier to learn lessons on how to build maintainable, reuseable, extensible, reliable code
    - refactor instead of rebuild: learn how to build slim and trim apis, optimizations rolled in over time
    - take the time to do it right (when appropriate): spend the time to predict how the code might be used. If it's a hack for the current problem, and you know it, do it right.
    - maintain it: keep libraries compiling and working together. Much less work in the long run.
    - prioritize api bug squashing: get rid of own api level problems that happen over and over. Come up with a solution which will prevent the problem from ever occuring again.
    - cache late: caching is a bane. Cache for speed when it works, not before. Avoid other types of sync issues (auto gen once at startup instead of caching on fs, etc)
    - lessen test time: decrease the amount of time it takes to see if a problem occurs. Run, puke, fix, repeat... as quickly as possible.
    - time spent is time gained: take the time to do it right and you get better at doing it right. Hack the dirty and you'll get better at dirty.
    - gain instinct: code lots. you'll get to the point that you'll do it right even when on autopilot.
    - lots of logs: log everything, and turn off the logging for deployment, wrap in if's to not affect speed.
    - count on cpu juice and lots of memory: boxes are much faster now, don't worry about each byte, atleast not at first.
    - allow yourself to make misteaks: you'll find out the reasons were valid in the first place.

    It's a big field, made up of little simple. Get good at the simple, be good at the big.

  99. but what kind of failure is safe by petermgreen · · Score: 1

    the problem is how to fail safely.

    VB (classic VB at least) defaults to fail=>terminate application. Turbo pascal for dos does the same. This was effective at preventing errors spiraling but can cause the user to lose a lot of work.

    Delphi defaults to fail=>leave event handler and give user a criticial stop message box. This means the user has a chance to recover thier work but depending on the failure things may be left in a very bad inconsistant state.

    neither solves the root problem which is going from deep in a nested tree of functions that touch data back to a state where the data is consistant while throwing away the minimum information possible.

    Checked exceptions are a possibility but i susepect few programmers would tollerate having every exception checked and it takes very strong discipline to write good catch blocks for every exception.

    Fail=>rollback is an option (this is what database servers tend to do) but it requires a lot of infrastructure to handle the rollbacks. This can be done at the OS level the compiler level or the application level but either way it is a LOT of overhead.

    --
    note: i'm known as plugwash most places but i screwd up registering that here somehow in the past and now can't register
    1. Re:but what kind of failure is safe by mkcmkc · · Score: 1
      These are all great ideas, and examples of what should be done. As you're implying, I don't think that the correct behavior can be chosen automatically--it requires design by the programmer.

      But, given that we have a situation where nothing has been explicitly done by the programmer, the question remains: what should the default behavior be? I would argue that in that (very common in the real world) case, errors should never be silently ignored, and that it's better to give the end user something to start from.

      --
      "Not an actor, but he plays one on TV."
    2. Re:but what kind of failure is safe by try_anything · · Score: 1

      An unsophisticated approach goes a long way to ensure sanity with exceptions and top-level exception handlers, even if the execution isn't particularly disciplined. There are lots of situations where a programming mistake, such as failure anticipate and handle a possible error condition, is much less harmful in the presence of exceptions than when using error codes that must be explicitly checked.

      First, if the application is going to fail, it's better that the user knows, and the sooner the better. If the application fails silently, the user can do hours of work based on a result returned by a failed operation, only to find out later that it was wasted. Or the user can wait hours for a job to finish, only to find out that the job produced bad output because of a condition that could have been detected near the beginning of the run.

      Second, some operations finish by updating an existing (good) dataset with newly calculated data. Obviously in this case it's preferable to crash rather than miss an error.

      Third, even when program crashes with no bad side effects, it is much better to have exceptions, because the exception can be caught and logged at the top level before the program terminates. This gives a chance to provide feedback to the user, who might be able to work around the exception quite easily if the error is obvious -- maybe the user entered a nonexistent path, expecting the program to create it for him, or something like that. It also gives programmers a chance of getting a decent bug report. The top-level handler might even be able to autosave all open documents and give the user a chance to recover them the next time he starts the program.

      I could go on, but you get the drift. Silent errors can leave users with corrupted files (destroying weeks of work), mysterious crashes (with no clue how to prevent or work around the error),
      bad data that appears to be good and affects important decisions made by the user, etc. On top of all that, it's much more professional, and more reassuring to the user, to terminate an operation or application with a message like, "FooApp has detected an internal error and is shutting down to prevent damage to user data. Please send the log file FooApp.log to [technical support|the developers] at bugfeedback@fooapp.com. We regret the inconvenience." This is terribly unsophisticated compared to the approaches you suggest, but it's within the grasp of almost any developer to add a top-level handler that logs a message and terminates the program, and the result is immeasurably superior to any approach that makes errors silent by default.

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

  101. Ranking of modded games? by tepples · · Score: 1

    but after people were so keen to mod my last 2 games, my new one (www.rocklegendgame.com) had pretty much every notable variable placed in an external text file (a fully commented one called config.txt in the data dir) with the express purpose of letting the techy gamer play with it. Some customizability makes comparisons of players' scores invalid. How does your design handle this?
    1. Re:Ranking of modded games? by cliffski · · Score: 1

      its a singleplayer game. If people want to claim they had a higher score than normal, then they can go for it. In singleplayer games, who cares :D

      --
      DRM-free indie games for the PC and Mac: Positech Games
    2. Re:Ranking of modded games? by tepples · · Score: 1

      If people want to claim they had a higher score than normal, then they can go for it. Hackability of a game without an easy way to get back to a verifiable standard configuration reduces the sense of achievement and in this way may reduce the popularity of the game.

      In singleplayer games, who cares :D Since the World Wide Web became popular, single-player video games with a score are only single-player in the same sense that bowling and golf are single-player.
  102. Java isn't always the solution by tepples · · Score: 1

    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. The trade-off is different when you're trying to get a (soft) real-time app running on a machine with a 67 MHz CPU and 4 MB of RAM. Is Java technology or any comparable system suitable for such a low-memory environment?
  103. You meant 'static const' by tepples · · Score: 1

    I believe that most compilers only bother allocating space for [a const] int if you try to take the address of it in some way. But when compiling an individual translation unit (i.e. an individual .c to .o or .cpp to .o), how can the compiler know whether or not another translation unit that will be linked into the same executable takes the int's address? I guess static const type variable = value; might work, just as a lot of GNU C and C99 guides recommend static inline for functions in header files.
  104. Mister obvious missed an obvious bug and... by frankShook · · Score: 1

    Found a bug in the author's code. This snippet will fail if it's in C. Otherwise, it's plain sloppy... // move all the aliens
    for (short i = 0; I MAX_NUM_ALIENS; i++)
            if (aliens[i].exists()) // this alien currently exist?
                    aliens[i].move_it();

    Also, repeat after me: DON'T WRITE VARIANTS ON THE SAME ROUTINE. While we're at it, take advantage of inheritance in subclassing!

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

  106. 100 aliens by tepples · · Score: 1

    I shouldn't #define MAX_ALIENS_ON_SCREEN_AT_ONCE to equal 100. That's way too many aliens to survive. How many aliens show up on the security camera at a USCIS naturalization ceremony? And if people can survive 100 Tetris pieces per minute, why can't they survive 100 enemy soldiers per screen?
  107. Wow, take a knife to a gun fight by caller9 · · Score: 1

    There are probably only a few ways to invite a can of geek whoopass more than to write a flawed introductory coding article and post it to slashdot.

    1) Claim evolution is false and/or use the oxymoron "christian science" seriously
    2) Say, imply, or imply by omission that linux sux.
    3) Get a portion of a formula wrong
    4) Diss an MMORPG
    5) Misunderstand something and write about it.
    6) ... you know the list.

    The biggest flaw in this guys discussion of C++ code was that it was a C discussion, and partially incorrect or misleading. C++ should follow some format of OO software engineering principles. Use case narratives, swim lanes, class diagrams, etc before the first line of code is written. Make everything autonomous, make it accept fuzzy inputs, make it do what it does and do it well even if widget A is v 2.0 and widget B is 1.8. Use stubs etc etc. Treat each class like a separate piece of software you may use later and plan on it being (hopefully attemptedly) misused by some dumbass 3,000 miles away you've never met.

    I think the biggest revelation for me as a beginning programmer was that before you code, you plan the code. It seems like a really simple idea. However, it seems that most people start with a loosely defined handfull of use case scenarios and just hammer that crap into existence. Then they're bought out by conglomerate X and vanish, money in hand.

    1. Re:Wow, take a knife to a gun fight by tedgyz · · Score: 1

      I think the biggest revelation for me as a beginning programmer was that before you code, you plan the code. It seems like a really simple idea. You make some good points, but to play devils advocate, I have experienced overplanning. Too much up-front design is a waste of time. I believe in evolutionary code. Refactoring is a necessary and important part of keeping a long running project from decaying into a blob of ravioli code (object-oriented spagetti code). As in so many things, balance is key. Design some up-front, but don't dig too deep or you waste your time.

      Treat every line of code like a work of art.
      KISS - Keep It Simple Stupid

      Having been coding as a job for 23 years, I can tell you that if you are good, you get to a point where you can code on the fly. I like to call it the stream of consciousness. Eclipse refactoring tools increased my productivity 10x-50x. I dunno if dawt-knet has that kinda stuff. I just do Java these days.
      --
      "No matter where you go, there you are." -- Buckaroo Banzai
    2. Re:Wow, take a knife to a gun fight by caller9 · · Score: 1

      I agree with what you said. I don't 100% practice what I preach. If it's a quick and dirty 400 lines of code to get something done fast then it defeats RAD to go over the top with planning. I was just trying to emhpasize that planning is required before you start. I've an aquaintence that had a hand in a govt. software project. The old system was lacking. They recirculated some requirements document into an encyclopedia of redundant or conflicting requirements and nothing got done. That is the bad end of planning/beurocracy and a blank, perpetual check. Private sector would invariably snuff that kind of thing, most likely in the direction of no planning with no consideration for those poor code maintenance guys.

      No planning on-the-fly coding works great as long as you 1) are as good as you think you are and 2) follow up with documentation later. If both are true you're in the 99th percentile, congrats you are nearly alone and should be paid accordingly. Hopefully you at least did 2 for when you eventually die.

      On lack of planning: The recent debauchery on the federal criminal database is another shining example of modification on the fly with sparse initial planning, a haphazard bloat-on-the-fly approach, and way too many cooks in the kitchen. It turned into a scrapped multimillion project with a bunch of probably smart people cutting each other's throats and a big story in the news.

      I get where you were coming from, everyone hates planning, they want to DO. A lot of the time it ends up being no big deal. From a company's standpoint having a lone genius guiding their future is very risky and often expensive to retain. On the flipside having drones make mediocre overplanned and bloated half-assed code is a terrible waste of energy. Also if you're a drone, I hear they have drones in India. It's a hard nut to crack I guess.

    3. Re:Wow, take a knife to a gun fight by tedgyz · · Score: 1

      You have some really good insight there. I probably AM in the 99th percentile. I'm a Software Architect now after slugging out code for many years. And yes, I have drones in India working for me. It took us about 5 years to find good Indian engineers that weren't inclined to run from job-to-job in the hot Bangalore market.

      I'll share my experiences from a past job at HP. We had a group of about 50 engineers - some of the brightest software people around - a lot of Phds. I had a lowly BSMA, so I was a grunt. Us grunts called ourselves the "rowers" and the Phds were the ones sitting on the "boat" doing nothing. There were some really bright people that could pontificate all day long about pie-in-the-sky ideas, but couldn't code their way out of a paper bag.

      In one case, I was taking over a project from a guy who moved onto something else. He wrote this painfully detailed design spelling out everything. When I took over, I used his design as a basis for my implementation, but I made some on-the-fly changes to simplify the design/implementation. We had code reviews there, so when he reviewed my code he beat me up that I didn't follow it to the letter. I tried to point out that his design was over-complicated and that I had implemented something that was easier to maintain, but he wouldn't hear of it. My final response was, "If you cared that much about it, you should have stayed on the project. Now Fuck Off and get out of my face."

      --
      "No matter where you go, there you are." -- Buckaroo Banzai
  108. How to keep your code from destroying you by Skevin · · Score: 1

    I just comment out the following function calls before rolling out to production:

    stab_programmer($employee_id);
    shoot_programmer($employee_id);
    drown_programmer($employee_id);
    strangle_programmer_while_sleeping($employee_id);
    frame_programmer_4_embezzlement($employee_id, $expense_fund_handler);
    mangle_programmer_with_factory_machinery($employee _id);
    insert_cyanide($employee_coffee_cup_id);
    break_nerve_gas_capsule($employee_cubicle_id);
    illegally_download_music($employee_computer_id);
    hide_bodies();

    I've already been fired twice from a Furby and an Aibo factory, but the Recall Process was efficiently quick.

    Solomon

    --
    "Twice half-assed makes an ass whole." --Solomon K. Chang
  109. Commenting Religion by Anonymous Coward · · Score: 0

    The idea that comments add to code maintainability is arguable at best.
    As a programmer who has worked with hobbyist, private sector, government initiative and open source projects I can tell you that like the code itself, comments are not made equal.

    A prime example is when a given function F allocates, but does not free memory on the heap in say C/C++ it would be wisest to document this with relation to the function. However comments which appear in source code are not necessarily the best documentation format, hence the scale of the project and the logistics of contractual obligations are the most common likely driving forces in systems documentation.

    There are of course sloppy programmers, documenters, managers and executives in nearly all information technology organizations, so if you have lots of options with respect to your career, have a good look at the environment the software is being maintained in before committing to a project.

    Personally the best case situation is where documentation is relative to version and off board in an appropriate file format which when displayed, allowing you to see documentation and associated source module in an agreeable visual and ergonomic format. Where if you make a change to source code you MUST update the documentation when relative line numbers change in order to keep the documentation in synch. (No, adding a blank line just shouldn't make it as a new version... "you cause it, you fix it" rule)

    As far as religions go, I'll stick to the following.
    John 14:6, John 14:28, Genesis 3:24

    Thank you and have a nice day,
        AS A : Systems Analyst

  110. don't comment what, comment why by Anonymous Coward · · Score: 0

    pragmatic programmer says that your code already says what it does, and if it doesn't then you haven't used reasonable variable and function names. Commenting it is repeating it, and fails DRY!

    Comment why code needs to do certain things, it makes more sense and may help people.

  111. Re:Use a language that checks I/O errors by defaul by cliveholloway · · Score: 1

    Heh, I wish strict and warnings were enabled by default too :)

    Trouble with using Fatal though is it confuses people who are good at catching their exceptions, because it just looks plain wrong. eg:

    use Fatal qw(open close);

    open(my $fh, '>', '/some/file')
    print {$fh} $text;
    close($fh);

    The exception handling is there, but because every open you see in good code is followed by an exception handler, it's hard to resist the urge to "fix" it.

    I've used it in personal stuff, but not in any production code...

    --
    -- Trinity in high heels carrying a whip: The donimatrix - there is no spoonerism
  112. Attn fledging programmers -- Code Complete by javabandit · · Score: 1

    Junior to mid-level programmers (those in the field less than five years)... please do yourself a huge favor -- check your ego and read the book "Code Complete" by Steve McConnell. (Hell, *all* programmers should do it).

    That single book will teach you to write maintainable, understandable, and clean code. It has examples in C, Pascal, and Ada, but the concepts contained within are applicable to all programming languages (except for maybe brainfuck and whitespace). It will also teach you what bad code looks like (coding horrors).

    Make no mistake. This book is the definitive work on how to write good code.

    1. Re:Attn fledging programmers -- Code Complete by freedom_india · · Score: 1

      I agree with you.
      Code COmplete (the first edition) is TOO good a book.
      I continue to read it even after 12 years in IT.
      However, not many of the new comers (esp. those with 75% and above) think of even reading it.

      --
      "Doing what i can, with what i have." ~ Burt Gummer
    2. Re:Attn fledging programmers -- Code Complete by Cederic · · Score: 1


      But then go and read Refactoring by Martin Fowler. Which will teach you how to engineer software, and not just write it.

      Code Complete is great, but it's also behind the times. That doesn't make it wrong, and it is still very valuable, but best practices have gone beyond it.

      Why settle for less than the best practices.

  113. Real programmers don't use comments. by Coolhand2120 · · Score: 1

    If it was hard to write it should be hard to read.

  114. Comments are evil... by clambake · · Score: 1

    /* doFoo() : This function explicitly turns on the foo flag and does foo. */

    def doFoo() {

            foo = FALSE;
            stopDoingFoo = TRUE;

    }

    Oops... forgot to change the comment didn't ya? A TEST would have made a better comment. A test that would FAIL when it's no longer TRUE.

  115. Lets get the ball rolling by Anonymous Coward · · Score: 0

    IBM is evil

  116. OT: Your sig by Alphager · · Score: 1

    "Mit der Dummheit kämpfen selbst Götter vergebens." would be the grammatically correct version of the sentence.

    1. Re:OT: Your sig by rah1420 · · Score: 1

      LOL

      You might search for my sig in /. and see that this argument comes up every freaking time I bother to make a comment. At this point it's a source of amusement to see if someone bites. (Hint: You're wrong, but if you want to think you're right, go right ahead.)

      --
      Mit der Dummheit kämpfen Götter selbst vergebens.
  117. The most important tip I would give a programmer by charlie137 · · Score: 1
    Don't reinvent the wheel.

    For example right now I have to work with a code made by other people, with there own lousy implementation of a regular expression parser. Crazy. not only it is probably full of bugs, but it also makes me waste my time having to learn there API that I will never use again.

  118. the virtues of assert()... by igomaniac · · Score: 1

    Someone mentioned this earlier in the thread, but it's really important. All good programmers I know use assertions liberally throughout their code. It will not only catch errors, but also serves to document the code as it makes the underlying assumptions clear to anyone looking at the code. Asserts are the C way of specifying preconditions, postconditions and invariants... Or to put it more simply, every time you think 'this pointer better not be NULL when entering this function' you do

    assert(pointer != NULL && "You're a moron for calling this function with a NULL pointer!");

    The && "comment" is a nice trick for having additional information when your assert fails...

    --

    The interactive way to Go -- http://www.playgo.to/iwtg/en/
  119. warm bodies from dot-com boom? by lpq · · Score: 1

    I can't help but wonder if those who expressed difficulty with the parallel programming subject were in the non-CS crowd.

  120. For intro, not bad by 192939495969798999 · · Score: 1

    If this is your first exposure to writing maintainable code, then odds are you shouldn't be programming for a living. Also, consider how bad IBM's code must be maintenance-wise if this is considered news! DOH!

    What's really news is that you could not do any of these maintainable code options and easily have a long career of programming. All your projects will be crap, but unless you seriously break something, it's unlikely you'll be fired just for being inefficient.

    --
    stuff |
  121. Re:The author could stand to read his own article. by StressedEd · · Score: 1

    Apologies, this is all "code",

    Considering

    for (short i = 0; i < MAX_NUM_ALIENS; i++)

    (N.B. corrected case of "i")

    There are even more nasty problems that could occur if down the line they decide that the maximum number could be very large and forget to change the types of the counter, consider the following, where we are "good" and use "typedefs".

    #include <iostream>

    /**
    * A warning to all on mixing short and long.
    */
    int main(void) {
      typedef short counter_type;
      typedef long limit_type;

      limit_type max_counts=65537;
      counter_type i=0;
      std::cout << "max_counts=" << max_counts << std::endl;
      for (i=0; i<max_counts; ++i) {
         if (i%128 == 0) std::cout << i << std::endl;
      }
      // You should never get here, unless you have a funny definition of short and long
      std::cout << "i=" << i << std::endl;
      return 0;
    }

    Do you (or other people out there) make use of compile time asserts, or numerical traits to avoid this type of problem?  Failing that do you have any solid tricks to avoid the above, apart from the obvious e.g. making sure the types of counters and limits are the same?

    A common problem I see with C++ is that you can do things in a very solid manner (e.g. type_traits, algorithm for_each) however at the potential expense of obfuscation - there's something comforting in a simple for loop... maybe that's just me.

    Any comments?

    --
    Be nice to people on the way up. You will meet them again on your way down!
  122. maybe not by unity100 · · Score: 1

    missing chances or catching them what makes billionaries of this sort.

  123. pretty smug replies by bl8n8r · · Score: 1

    I've met people that can write some pretty ideal code, but the problem is these are usually very difficult people to work with. Idealism is a nice start, but when you get into the gray area of people and personalities it's not a good fit. Why? Because everyone has a different idea of what is "right". There needs to be enough flexibility on a team for people to accept this or projects go tits up. When they do, the Idealists always stand around for a couple days bitching about it while everyone else slops things together to get them out the door.

    Clue: At this point, nobody really cares hearing about the "right" way to do it. We just want to get the damn thing done. Standing around, pissing-and-moaning, is like putting and anchor on a sinking ship.

    --
    boycott slashdot February 10th - 17th check out: altSlashdot.org
  124. I love you by Anonymous Coward · · Score: 0

    You, sir, are a legend. The Exile games rule. I bow to your greatness.

  125. Re:Use a language that checks I/O errors by defaul by CastrTroy · · Score: 1

    Maybe I just don't remember correctly, but I remember that java supported the "throws" keyword, which when put after the method, let the compiler know that your method was capable of throwing an exception. Also, when that method was called, it would require that you catch the error, and do something about it. Or at least continue throwing it up the chain. I would like to know when changes are made to the API such that an exception would be thrown so that I could at least handle it correctly. As it stands with VB, you have no way of knowing which exceptions are to be thrown, and therefore you can catch everything at the GUI level, but if you don't know what types of errors to expect, then it's hard to handle them properly. Also, it stops you from doing any proper clean-up in the immediate area where the error occured.

    --

    Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
  126. For inquisitive newbies: learn to use Usenet! by Anonymous+Brave+Guy · · Score: 1

    It's certainly an unfortunate reality that there is much material about programming on-line, but relatively little of it is really good, and it's by definition impossible for someone new to a given area to work out for themselves which is which. Indeed, it's might be that the best technical content isn't the best written, and that the wonderfully easy-to-read stuff is littered with dangerous misconceptions and technical errors.

    If you've got the patience, I've written a few fairly detailed posts here in the past with good starting points for those learning various aspects of programming: on-line resources you can usually trust, book lists, that sort of thing. Google seems to do a reasonable job of handling Slashdot's archives, so go ahead and browse. Just ignore me when I'm ranting on some political subject. :-)

    If there's one piece of general advice I'd give for those looking to learn on-line, it's learn to use Usenet. Unlike your average programming web site, programmers who frequent the various language newsgroups tend to be pretty competent. More to the point, their replies to questions tend to be effectively and constructively peer reviewed, making them more accurate and often more insightful than any most people's personal web sites. There are newsgroups for most popular programming languages, as well as for many specialised programming areas, programming for different operating systems, using different programming tools, etc. You can access these using services like Google Groups if your ISP doesn't have a Usenet server. Look for the comp.* hierarchy, particularly comp.lang.* for different languages (and alt.comp.lang.learn.c-c++ if you're learning either C or C++).

    Most of these groups have a decent FAQ that you should read before starting, to determine the best place to ask your questions. For instance, questions about particular operating system APIs or development tools are often off-topic in the generic programming language newsgroups, since they will only apply to people using that language with the specific OS or tool, but the same question might be perfectly reasonable in another group. The FAQs also tend to have good lists of books and tutorial/reference web sites you can trust. If you start from those, then for the most part, things they link to will also be fairly trustworthy. Just don't go and put something like "Java tutorial" or "learn Python" into Google and expect the top ten hits to be great, because most of them will probably be hobbyist sites written by enthusiastic but not terribly well-informed or experienced people.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  127. To the "need no comments" theorists by worldcitizen · · Score: 1

    Can you really write code so cleanly that doesn't need comments?

    When writing code for a real system (and not a theoretical one) you come across situations (boundary cases, platform limitations, etc) where you try something and realize that it doesn't work. Negative knowledge is valuable to preserve and the best way to do it is using comments. Whether you can write cleanly or not is completely irrelevant in these cases.

  128. He comments too much by Peaker · · Score: 1
    Its better to use self-explanatory code where possible.

    Using his example:

    // Calculate the bullet's new position.

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

                    [Small chunk of code.]

                    Return is_destroyed;


    Instead, use:
                    advance_bullet_position();
                    find_bullet_collisions();
                    check_bullet_path_end();
  129. too late ... by hachete · · Score: 1

    it's got me send he

    --
    Patriotism is a virtue of the vicious
  130. Re:The author could stand to read his own article. by SanityInAnarchy · · Score: 1

    I would say that the first mistake is using C++ at all for "Kill Bad Aliens". Even coding it in Ruby would probably be fast enough for most machines, though I'd probably use Python or something.

    The second problem here is, why would you have a separate type for counter_type and limit_type? I guess I can imagine something like this happening in a larger context, but it seems like the above should probably be the same type.

    As for what I'd do to prevent the above, I'd use unit tests. That way, I'd know exactly where the infinite loop was, as soon as I changed the type of either limit_type or counter_type, and it probably would not take me very long to figure it out from there.

    I understand that a simple "for" loop may be comforting, I grew up with them too. But most of the time, there's no reason for it, and you'd be better served with a Ruby-like iterator. Something like:

    max_counts=65537
    max_counts.times { |i|
            puts i if (i%128 == 0)
    }


    That's assuming you actually need to count to 65537 and have i in the first place. Usually, you have a for loop because you need to iterate over something, which means you'd be better served with something like a foreach loop:

    my_stuff = ['one', 'two', 3, 0.4, SomeObject foo, somevar, and, so, on]
    my_stuff.each { |x|
            puts x
    }


    Of course, the especially cool part about Ruby is that I'm ignoring types here entirely in the values I'm printing. In general, all I need to be able to print an object is for it to have a to_s method, allowing it to be implicitly converted to a string -- which I think is a lot nicer than overloading bitwise operators, the way iostream does.

    But you can see here, even if I was concerned about integer types in Ruby -- and I'm not, Ruby seems to automatically flip over to the BigNum library as needed -- the latter form avoids even needing a counter, or assuming that what I'm iterating over looks like an array at all. It's usually much more efficient to implement one "each" method than to overload [] for strange types. Consider something like a parser:

    xml = new SomeParser('hithere')
    xml.each_token( |x|
            do_something_with(x)
    }


    I'd say the majority of problems match much better onto something like that, where it can simply walk through the string, parsing as you go, than something like this:

    for (i=0; i

    In that example, it now has to parse xml's string entirely at least once to get the number of tokens, and it'd really be better off just caching it as an array, since we could theoretically want random access to it.

    Now, there's nothing stopping you from implementing all of the above, and more, including the traditional way to do it:

    while (defined(t = xml.next_token))
            do_something_with(t)
    end


    But there's another disadvantage for simply asking for next_token. You now have to remember to reset it somehow, otherwise the next thing to want to iterate through is going to get a big fat NULL.

    Also, you've lost something else: "each" is generic. There are standard library functions, and certainly user libraries, which know how to use each. Even if you can't think of a use for that, it helps that you already know how to use foo.each, even if it's something weird like foo.each_token. And maybe it's just me, but it looks a LOT clearer than certain other libraries I've used which pass around callbacks, even if it's effectively doing the exact same thing.

    Despite the fact that most of my examples are in Ruby, I really don't like Ruby. I think it's like Perl, but with even more emphasis on strings, and it looks like it will be dog-slow for a very long time. But it does make for very quick hacks, and it's certainly sufficient for a Kill Bad Aliens game.

    --
    Don't thank God, thank a doctor!
  131. Re:The author could stand to read his own article. by SanityInAnarchy · · Score: 1

    Erm... One of those examples had xml, and I forgot to escape it for the web... that should be

    xml = new SomeParser('<a><b /><c>hi<d>there</d></c></a>')

    Also, the example's a bit contrived, given that real XML parsing in Ruby is usually handled by REXML, which does do all the parsing upfront (as far as I know; there's enough abstraction that it might not), and stores it in not just arrays, but recursive object structures that more closely reflect what XML looks like.

    --
    Don't thank God, thank a doctor!
  132. Re:Use a language that checks I/O errors by defaul by ClosedSource · · Score: 1

    "I would like to know when changes are made to the API such that an exception would be thrown so that I could at least handle it correctly."

    And you think getting a compile errors is the way to figure that out?

    "As it stands with VB, you have no way of knowing which exceptions are to be thrown.."

    Of course you can, it's documented. How do you know what any method does if you're not checking the documentation?

  133. lol define by Anonymous Coward · · Score: 0

    Is this guy kidding me? In the intro he claims to be using C++, and then the HEADLINE of one of his points is to use #define? WTF. Get this guy out of here

  134. Profit? by Icarium · · Score: 1

    1. Get paid to write code (Mine). 2. Get paid overtime to fix code (Mostly other people's). 3. ??? 4. Profit! In this case "???" consists of a manager asking me politely to comment my code once a year, while simultaneously offering me a nice pay increase. Having said that, the only code that I've come accross that I simply couldn't figure out what was potting was usually my own, and usually as a result of "We told the client this will take a week to develop, but they need it tomorrow. Here's some money, make it so." Hey, if it works and the client is happy, I'm happy.

  135. Picking it apart by HouseArrest420 · · Score: 0
    Wow, not that this is a first that I've seen on /. but seriously, why does everyone have to pick apart what was written.

    1. It was written for those that are just starting out with programming----that's obvious. But all of you would rather point out how obvious the "tips" are, while missing this VERY obvious point.

    2. Who cares if the code actually works or not? Are you going to copy his game? Are you going to use his work on your resume? NO....and if you do......lol. It's written to show a point, just like any beginner tips.

    3. The point in generalizing with things like teaching tips to people new to programming, isn't the code. Its how its written. And while I cringe at the idea of languages that don't follow set way to....say indent, you can't say his exammple's wouldn't prove useful to someone that's never programmed before. Personally I wouldn't have used a game to show it, but anything that can catch the attention of anyone new to the religion is good, so I can see why he did.

    Some of you are acting like when you first sat down and typed in "Hello World!" you ALREADY knew where and when to comment, damn I bet most of you C programmers that taught yourself how to program started out saying shit like (of course out loutd) cowt gets "Hello World" instead of saying c out gets "Hello world!". For most of you I bet it was some time before you even had your first "away from desk" coding experience, you know what I'm talking about....that last block you couldn't get right while you were at your desk, now your in Burger King writting down ideas on a napkin during your lunch break.

    Now, 2 years after you start writing code that's worth a shit you wanna pick apart the work of anyone that tries to help the guy you used to be.

    --
    This is Slashdot! Give me the latest gadget, bug, or OS project! This ain't english class so don't confuse the two!
  136. I'm still eagerly awaiting the sequel... by Anonymous Coward · · Score: 0

    How not to get sued by Atari for a Bazillion bucks.

  137. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  138. Yeah... Why is assembly so terse by Colin+Smith · · Score: 1

    What's wrong with MoveImmediately rather than MVI?

    --
    Deleted
    1. Re:Yeah... Why is assembly so terse by Mr+Z · · Score: 1

      Because the screen real estate and keystrokes consumed by an item should somehow be related to how much information content it has? Compare and contrast:

      1. MoveImmediately #1, R1
        MoveImmediately #3, R2

      2. MVI #1, R1
        MVI #3, R2

      3. R1 = 1;
        R2 = 3;

      Of the two mnemonic-assembly examples, which most closely resembles what you might write in any other context (i.e. the third example?) Hmmm. Maybe the same reason you write "a + b" rather than "perform_addition(a, b)" and most people use i, j, k for index variables instead of "array_index". (Though there are exceptions to the latter, and those people quite frankly are nutty.) :-)

  139. Re: That's just hiding your complexity by GargamelSpaceman · · Score: 1

    Umm.. Hiding complexity is a GOOD THING. Think about this, internalize it, and embrace it.

    Most of the time, if confronted with a function that makes a peanut butter sandwich, say called make_pb_and_j() then we expect to find simple high level instructions on how to make a pb_and_j, something like:

    make_pb_and_j() {
    var plate := get_plate_from_cupboard();
    var knife := get_knife_from_drawer();
    var bread := get_slices_of_bread_from_bag( -slices=>2 );
    var pb := get_peanut_butter_from_cupboard();
    var j := get_jelly_from_fridge();

    bread.put_on( -where=>plate );
    knife.scoop_spreadable( -from-jar=>pb );
    knife.spread( -on-what=>bread );
    knife.clean();
    knife.scoop_spreadable( -from-jar=>j );
    knife.spread( -on-what=>bread );
    knife.lick_clean().yum().put_in_dishwasher();

    var sandwich := put_sandwich_halves_together( -halves=>bread );

    return sandwich;
    }

    We don't want to find instructions on how to go to the grocery store and buy the bread, or AI on how to earn money with which to buy the bread, or instructions on how to grow the wheat or till the field, or even to make the bread. ( or peanuts or the strawberries for the jelly, or how to fire clay into a plate or smelt ore into steel to make the knife etc )

    All those complex actions are necessary in order to make a peanut butter and jelly sandwich, but I don't need to know about them to make a pb and j because in the above example this complexity was nicely hidden in the get_xxx_from_xxx functions. Given a get_fluff() function, then if I want to make a fluffernutter, then I need only change a few lines.

    What too often happens is that someone is given a make_pb_and_j function and they need to make it into a make_peanut_sandwich( -topping ) function that can either make a fluffernutter or a pb_and_j. Instead of creating a get_fluff function, since fluff is pretty simple to make, they lazily add the logic of what would have been a get_fluff function inside an if block: ( I had to delete the example because of the lameness filter )

    That expanding out all the steps into if-blocks makes for hard to read code is obvious. They teach programmers not to do this in CS 101, but that course is hardly necessary to appreciate the common sense fact that information hiding is a good idea.

    Now if a programmer wants to be able to maintain their code, then they follow common sense good practices, but in a group, this falls apart. The goal of a programmer is usually not to create maintainable code. It is to collect another paycheck without getting fired. Writing good, or maintainable code is bad for one's career. Writing good, elegant, maintainable code and working efficiently are only good goals when you yourself reap the benefits and suffer the consequences resulting from the quality of the code - i.e. you are your own boss.

    Consider what happens to the 'good programmer' who insists on writing good code, in a group of 'bad programmers' who don't insist on any such thing:

    Someone, a 'good programmer' who takes the time to produce easy to read, maintainable code takes on the extra work entailed by producing quality product. But they are measured against 'bad programmers' who just add another nested if statement to whatever 20 page long pile of crap method they are coding..

    Now every bit of 'good code' that the 'good programmer' produces is MUCH easier to read and work on than the crap everyone else produces. Everyone who has the pleasure of being assigned to work on it gets their project done either ahead of schedule or with time to fart around on slashdot. Working on good code makes you look good.

    But working on bad code makes you look bad because you have to read and understand horribly byzantine piles of interconnected, pasted and unfactored crap to m

    --
    ...