Friday, June 2, 2006

Assertions

I worked on a horrible, interesting bug today. But first, some background: assertions. If you're a coder, assertions are probably the best thing that you've probably done in your code before you even knew they were called assertions, and something that they should teach in CS classes. (I didn't learn the proper term for them until I started here.) Simply put, they're this:

Assert(everythingIsOkay, "Crap! Something's broken!");

The macro Assert would then expand to something like this in a debug-only build:

if (!(everythingIsOkay)) Output("Crap! Something's broken!");

So, you litter your code, especially at the beginnings and ends of methods, with these assertions to say that you're sure that when you get to that point, something will be true. This object will never be null. This counter will always be at least 1. The user is currently logged in. Stuff like that. They let you know immediately if some other part of the program is broken. They don't affect the performance of final versions of your program, because final versions that ship to customers aren't built in debug mode, and assertions disappear automatically in final builds.

Anyway, we use those all over the place in SharePoint Designer. When you're using a debug version of SPD (customers never see debug versions), you get a message box popping up telling you what went wrong. But today, I worked on a bug that's like a bad time travel episode of Star Trek: the reason that we crashed was because we asserted that something bad was going to happen. The very act of showing that warning dialog is what caused the actual crash to happen. (I won't get into the details of how exactly that is possible because they're pretty arcane...)

Sure enough, if I get rid of that dialog, everything is peachy-keen. So, there's no actual bug that will affect a user, because only people on my team will ever be using these debug builds of the product.

Ah, that was amusing. Amusing and frustrating, because I spent so much time looking at it. But, I'd been looking for an excuse to talk about assertions for quite some time, seeing as I have all sorts of readers who write code only occasionally, probably haven't thought of them, and can probably get some use out of the idea.

7 comments:

Travis said...

THE FOLLOWING POST LOCATION IS RESERVED FOR IANONYMOUS TO TELL US HOW MUCH BETTER HE IS THAN US.

ianonymous said...

Sorry to disappoint. I was just thinking that I should make a better practice of using assertions rather than encapsulating that kind of functionality by throwing an InvalidStateException or relying on unit tests to cover it.

Sadly assertions didn't appear in my precious Java language until JDK 1.4 and it is difficult to teach an old dog new tricks.

Although, kudos for trying to beat me to the punch … you appear to be learning ;)

Travis said...

A lot of my older programs would just have functions that would return immediately in a case where I should have just asserted, which is kind of missing the point. It's error handling for error handling's sake. I guess the point is that it would skip over the code entirely and probably make the error very obvious, but it's still not really the right way to go about handling a problem, because it still has the potential of obscuring an error. VB even supported proper assertions (Debug.Assert()) but I never bothered using them because I had no idea what an assertion was in the world of code.

Kerjo said...

You'll be happy to learn that Elbaum has made that part of his curriculum for the semester.

Matthew Johnson said...

It was part of our software engineering curriculum too. I guess Travis just missed out on the fun.

stolee said...

I don't like the way they are implemented in Java, especially because using runtime exceptions tells you more about what happened than the assertion. Also, assertions only compile and run if you set certain flags.

I remember a chapter on these in first semester, but no one cared because they never tied it in with testing.

Travis said...

Part of the draw to assertions is that they only compile with certain flags. You generally don't want assertions running in the final version of your app, because it's extra code running that doesn't really have a point, and depending on what the assertion says, it could slow things down considerably. There are some exceptions, like "release asserts," which World of Warcraft uses so that things that go wrong can be logged without interrupting the user.