Archive for the ‘Programming’ Category

Was it a bug?

Monday, April 13th, 2009

If you’ve read the news today - particularly the gay news - you may have discovered that Amazon has “chosen” to remove all gay & lesbian items from their best seller lists. Now, usually I’d be the first to complain about something like this, but I’m also a programmer. As such, the possibility that it might actually be a bug as Amazon claims isn’t that hard to believe. Writing a new algorithm - which they’ve clearly done - always brings with it the risk of mistakes and bugs. I’m not saying that that is what has happened, but you know? I’m giving them the benefit of the doubt for now.

Now, if they haven’t fixed the issue in a week or two, that’s when I’m going to get upset.

Using an ostrsteam correctly

Thursday, November 20th, 2008

At work, I recently ran across a bug in some legacy code using ostrstream. As it turns out ostrsteam is extremely bug prone. In fact, ostrsteam has actually been deprecated in favor of stringstream. If you’re writing new code, do yourself a favor, stop now, and go use stringstream.

If you can’t - say you’re maintaining legacy code - I strongly advise checking to ensure that your code follows the pattern below. If you’re not - and you’re using dynamic buffering (the default) - you probably have at least one bug and one memory leak in your code.


/* By default the constructor allocates a 512 byte block of memory which is managed by the object itself. */
ostrstream stream;

stream << /* some data */;

/* This is the first bug fix. An ostrstream is a BINARY stream. It is not NULL terminated by default, even when calling str(). Since an allocator is not guaranteed to give you a zeroed block of memory, your string may be much longer then you expect. This could cause memory corruption, data corruption, or stack dumps. (Mine was the first two and was a royal pain in the ass to track down.) */
stream << std::ends;

/* Not absolutely required, but the second parameter is an example of paranoid programming. Just in case someone comments out the line above, you'll still be safe from memory corruption. Note: Depending on you're implementation of string, you might get a string with two null characters at the end. This shouldn't cause any problems, but is worth mentioning for clarity sake. */
std::string str( stream.str(), stream.pcount() );

/* This is the fix for the memory leak. The str() call above gave the caller (you) responsibility for deleting the dynamically created buffer. Rather than worry about how that buffer was allocated (new[] versus malloc), you can just tell ostrstream that you don't have a reference to its internal buffer and it will take ownership of the buffer again. Thus the dynamic buffer gets deleted when stream goes out of scope. */
str.freeze(false);

Now if only more UI designers would read this

Tuesday, November 18th, 2008

I have occasionally been tempted to write a post/rant about about interface design. Instead, I’ll just refer you to a couple of useful resources, and say “what they said!”

What reading Tufte won’t teach you: Interface design guidelines - Simply stated rules for designing UIs.

User Interface Design for Programmers by Joel - If you haven’t read this, and you claim to be a UI programmer, who the heck are you kidding?

more to come.. Suggestions welcome.

Cognative Bias: Jumping to Conclusions

Sunday, July 20th, 2008

A few days ago, the folks over at the Business of Software blog posted an article on how the human minds tends to jump to conclusions. For me, this turned out to be a fairly timely article that I kept coming back to over the last couple of days.

This artificial experiment is an interesting illustration of a couple of human tendencies. First of all, we jump to conclusions. Secondly - more important, but also far more subtle - we tend to seek out evidence that confirms our hasty conclusions, rather than evidence that might contradict them.

At work, I often find myself trying to make educated guesses from very little information while trying to debug issues found in either QA or released code. One of the things I’ve gotten burnt by several times now is exactly the type of failure to test my initial conclusions that this article describes. I’ll be fairly convinced of my initial conclusion, mention it to someone else, and have them shoot (what were in retrospect) very obvious holes in my theory. As a result, I’ve been trying to apply a much more systemic approach to confirming my initial theories before taking them to anyone else. It’s been helping so far; at least when I remember it that is! Overall, I highly recommend this one for anyone who has to solve problems with insufficient information.

As for the Business of Software conference itself, man do I wish I could afford to attend. Sounds like it’ll be a blast, but at “only” $1495, that’s not going to happen anytime soon.

Preventing Magic Numbers

Friday, January 5th, 2007

This post will most likely only make sense to people who have programmed in C/C++.

It seems like trying to prevent programmers (sometimes even good programmers) from using magic numbers is a never ending task. Today, I thought of a possible idea to prevent them or at least catch them fairly quickly. Basically, you could use a preprocessor to randomly select the numerical values for #defines on each compilation. This way ever built would be internally consistent, but any attempt to hardcode a magic number would quickly fail. (Note that I’m assuming a decent unit test suite to help locate/catch the errors.) Each time the system is built, the #defines change and all the magic numbers stop working. Now we have a bunch of test failures and can easily find the “brocken” code segment. So in a header file you’d have something like this:

FLAGS(name1, name2, name3)

OR
FLAG(name1)
FLAG(name2)
FLAG(name3)

which would be respectively processed to:

#define name1 random_int
#define name2 random_int + 1
#define name3 random_int + 2
OR
#define name1 random_int
#define name2 random_int2
#define name3 random_int3

You’d also need something to handle maskable flags. Currently you might have this in a header file:

#define flag1 0x01
#define flag2 0x02
#define flag3 0x04
foo(flag1 | flag2 | flag3, etc...);

You’d need to replace this with a method of auto generating the power of two masks. The new header might be:

MASKABLE_FLAGS(flag1, flag2, flag3)

The beuty of this is that all the existing tools, build structures, & code continues to work. The only thing that changes is that now the magic number usage gets quickly caught and filled as bugs. Combined with an IDE or compiler that warns on magic numbers, this might work for a fairly large software project.