C pitfall: typo in variable initialization

Apparently C allows a variable's initialization to refer to the variable being declared, as in

int x = x;

I guess the reasoning is that by the time the compiler reaches the initialization on the right side of the "=", the declaration on the left side has allocated memory for the variable, so the variable may be referenced.

This language feature may have its uses, but it can also lead to subtle bugs. I just fixed a bug that boiled down to the fact that the following compiled and ran:

- (void)wtf:(NSString *)ping
{
   NSString *pong = [pong self];
   NSLog(@"%@", pong);
}

The first line of the method should of course have been

   NSString *pong = [ping self];  // ping, not pong

but due to copy-paste and variables looking alike, I didn't spot the typo until our QA guy reported a crash and his stack trace led me to this method.

By coincidence, the code had worked correctly for me every time in development. In the debugger, I printed the value of pong on entry, and it happened to be the value of ping, presumably because that was the leftover value that happened to be on the stack.

I don't think this is a compiler bug. I believe the C standard allows the incorrect code I wrote, for two reasons. First, I created a scratch project and compiled the above wtf: method verbatim with GCC 4.2, LLVM GCC 4.2, and LLVM compiler 1.7. Second, I vaguely remember someone posting a trick for creating variables with unique values for use as the "context" passed around by KVO. I think the trick used this feature of C.

Update: I think the KVO trick was something like

void *x = &x;

I guess there no reason to disallow this, since it's equivalent to

void *x;
x = &x;

So now that I think about it, my bug wasn't really related to initialization. I could just as easily have made my mistake this way:

- (void)wtf:(NSString *)ping
{
   NSString *pong;
   pong = [pong self];
   NSLog(@"%@", pong);
}

IKImageView's mysterious delegate

Martin Hewitson asked this question a little while ago on cocoa-dev:

Does anyone know what messages the delegate of an IKImageView will get? I can't find any documentation or examples.

I was surprised to find there is indeed nothing about this in the docs. I Googled "IKImageView delegate" and the top hit was page 2 of an article posted by Dave Jewell for The Register in 2008. The article lists delegate methods that seem to have been discovered via class-dump.

In 2010 the question was asked again and still not answered in the docs.

I hoped the methods might at least be declared in a header, but the following returns no results:

$ cd /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/ImageKit.framework/Versions/A/Headers/
$ grep imageWillChange *

Apple's own IKImageViewDemo example code sets the delegate but never implements any delegate methods.

Searching StackOverflow does not find anybody asking this question, although there are plenty of other questions about IKImageView.

So here is a class that has been around since 10.5, that people are clearly using, and its delegate has never been documented? Why hasn't there been more of a clamor about this?

If you implement one of the methods listed in Dave Jewell's article, will Apple reject you from the App Store for using an undocumented API?

Jewell wrote:

In fairness to Apple, the lack of documentation is probably due – in part – to the complexity of the ImageKit framework.

I think that's way beyond fair. We all have bugs in our work, whether it's code or documentation, but I would find it odd for someone to excuse a glaring bug of mine out of "fairness".

I just filed rdar://10114629.

My WordPress plugins

I just replaced the WordPress plugin I use for enabling Markdown on this site. I've already forgotten the name of the plugin I got rid of. All I know is that it was giving me headaches when I went to clean up code snippets in people's comments. The right Markdown plugin to use is either PHP Markdown or PHP Markdown Extra (I use the latter) by Michael Fortin.

Here are all the WordPress plugins I use on this site:

  • Akismet. Spam blocker.
  • Markdown Extra. This is how PHP Markdown Extra is listed (without the "PHP") on the WordPress admin page for plugins.
  • MediaElement.js. For embedding video and audio. I used this to embed mp3 files in my two posts about Cantonese text-to-speech.
  • Unfancy Quote. Replaces the curly quotes that WordPress generates with straight quotes. I installed this so that code snippets don't get messed up.
  • WP-Syntax. Applies syntax highlighting to code snippets.
  • WP Super Cache. Page caching, aka protection from being Fireballed or Slashdotted. Hey, you never know.

By the way, both Markdown and syntax highlighting work in comments as well as posts. If you want to include Objective-C code in a comment, you can wrap it with <pre lang="objc"> and </pre> and it'll be syntax highlighted. One of these days I'll get around to making that clear in the comments UI itself. I should really look for a plugin that will allow you to preview comments, but that'll have to wait until the next iteration of my procrastination runloop.

Lessons from James Garner

Never mind that I'm not in show business; I wish I could have worked for James Garner. In his book Enchantment, Guy Kawasaki quotes this story told by Stephen J. Cannell, the creator of "The Rockford Files".

There were occasions when I sent a script down to him that I didn't think was the best script that we'd ever shot, and I'd never hear from him. A lot of other actors I worked with over the years would call me up and say, "Hey, I don't think this is a very good script, we need to do this, this, and this…" Never a word from Jim. Nothing. He'd just do it. So I started to think that he didn't see that it wasn't a good script.

Once we were at a wrap party at the end of a season, and one of those weak-sister scripts came up. Jim wagged a finger at me and said, "Not one of your better efforts, Steve."

So I said, "Okay, let me ask you a question: Why don't I ever hear from you when you don't like the script?"

He said, "I'll tell you exactly why: I trust you and I trust Juanita [Bartlett] and I trust David [Chase], and I know if you send me a script that isn't quite up to what we're used to doing, it's because it's the best you can do that week given the pressures that are on you. And if I spin you guys all around and force you to rewrite, I'm going to turn one bad script into four bad scripts.

"So that's the time that the acting department has to step up and really kick some ass. We have to step up and really make the stuff work. I have to look for more motivation to make comedy where I don't see it on the page and try to make it go past the audience without them seeing that it wasn't that good a story."

Whoa. I mean, come on. What a pro! What a pro! And he's right: Very often I've found that when actors have spun me around like that–I know the script's not as good as it should be, but let's get past this one and have a good one next week. You can't do twenty-two excellent shows–it's just not possible. Anybody who does series television will tell you that. There's always a few that aren't as good.

He told me, at the same time, "You never sent me two bad ones in a row."

For a guy like that, I would make extra sure not to send two bad ones in a row. There are lessons in this story about trust, professionalism, and appreciation for the hard jobs other people do to help the star succeed.

I watched the whole Rockford Files series last year and was surprised at how good it was. Maybe I can appreciate it more now than when I first watched it as a kid. A friend told me Garner's old show "Maverick" is also excellent. I've been meaning to check that out too.

Three notes on typing (the keyboard kind)

Note 1: typing too fast

Lately I've noticed that when I type too fast for my Mac to keep up, the character input is sometimes not only delayed but out of order. Just recently, "To " came out as "o T" and "I didn't " came out as "idn't I". (A "d" got dropped in the latter case, but I can't say for sure I didn't accidentally leave it out myself.)

Anybody else seeing this? I don't think I ever saw it until recently. These examples suggest that it's not a simple case of me transposing two letters by mistake. It looks like the first character in my burst of typing gets pushed to the end, but I'll have to collect more examples to be sure of any pattern. I think it usually happens in my web browser — I forget which one.

As I recall, NeXTstep always guaranteed not only the character order you typed, but that the keyboard events would go to the window that was key at the time you typed them, even if for some reason they were delayed so long that you had already switched windows. I don't know if this is guaranteed on the Mac; I've never assumed it was. But I'd expect the events to at least be in the right order.

Note 2: cloud-based text editors

I use various "cloud-based" text editors on my iPhone — most often Elements, sometimes Simplenote, and rarely others. These editors synchronize local text files with either Dropbox or a web service, depending on the app.

I've noticed that if I launch one of these apps and immediately start typing, one of two things often happens:

  1. The app scrolls to the bottom of the text file and what I type is appended to the file instead of inserted where the cursor was when I started typing.
  2. I type a phrase and when I look up from the keyboard I see the phrase has been inserted twice.

I assume both of these are because I start typing before the app has finished retrieving the latest version of my file from the web. In the first case, my guess is that the app blocks while it retrieves my file and displays it in the editor view (thus putting the insertion cursor at the end), and only then does it handle the backlog of keyboard events.

In the second case, my guess is that the app is trying to be helpful. It remembers where my insertion point was, buffers my keystrokes while it asynchronously retrieves the file, and when the file has been retrieved it plays back the buffered keystrokes at the remembered insertion point. I'm guessing there's a bug in the "playback" code, but again, this is just a guess.

The workaround is to wait before I start typing. I wait until the network-activity indicator at the top of the screen stops spinning, and then I type. I would prefer that the apps enforce this workaround by making me wait. They should not let me start typing until the file is retrieved. I appreciate that these apps want to create the illusion that I can treat my files as if they were purely local, but I think this illusion is unsustainable.

These concerns are one reason I wanted to stick with Notespark, which has a different syncing model and does three-way merge instead of wholesale updating with the newest version of a file. It's a good app. I forget why I don't use it any more.

Note 3: not looking

A bit of personal trivia: sometimes when my eyes get tired I close them for a few seconds but continue typing. I do it when typing both code and prose. I kind of like the mental state this puts me in and the way it forces me to use my mind's eye. As a variation, sometimes I keep my eyes open but look away from the screen. Try it some time, you might like it.