On Jul 16, 2009, at 1:58 PM, Bill Bumgarner wrote:
Then your macros are buggy.

According to the rules now, quite possibly. But the rules are kinda busted.

One place that looking at *outError and being able to assume it would be nil on the *entry* to a NSError-returning method is when you are stacking errors. This is woefully underused in general, but NSUnderlyingError is very useful for diagnosing reports from users. I don't want to get a report from a user that says the document couldn't be saved. I want one that says "the document couldn't be saved _because_ the file x couldn't be written _because_ the disk is full". NSUnderlyingError is *great* for this, so encouraging its use would make my life easier. As an aside, I'm not proposing displaying the full error stack to the novice user in an NSAlert, I just want it for debugging/support.

  So, if you have:

- (BOOL)foo:(NSError **)outError;
{
        if (![self bar:outError]) {
                xxx;
                return NO;
        }

        if (something else bad that doesn't use NSError) {
                yyy;
                return NO;
        }
}

then at "xxx" you'd like to build a new NSError that has *outError (if outError != NULL) as the underlying error. This is perfectly OK since we are on the failure side. Unless the developer of -bar: forgot to actually set *outError (clang should check this, see the Radar below) — so this is yet another case where a convention of setting it to nil and leaving it alone would be helpful. I'd rather get some less informative error stack than a crash.

But, what would be really convenient, and thus reduce programmer error, would be to be able to use the same macro at "yyy" were we are creating a base NSError w/o any underlying error. As the calling convention stands now, we can't since we can't depend on the caller to have initialized *outError. So, instead we have to remember to use two different patterns of code depending on whether we are creating a stacked error or a base error. This is especially fragile under code motion when refactoring (can lose the hook to an underlying error or start mistakenly looking at pointer contents we shouldn't).

Sure, the rules are the rules, and we should follow them or fear unexpected sudden termination. But, if these rules are the indented behavior, I would respectfully submit that the intension is the buggy bit =)

Performance is a non-issue here. Correct behavior on the (relatively rarely tested) error path and programmer convenience are the issue. I love NSError, but a revised set of rules would make it less sucky to use. And, of course, with clang-sa we have some nice tools to help people migrate to a better set of rules (Radar 6990911: clang should check more NSError conventions), perhaps in some glorious 10.N future.

I note the nil-initialization problem in that Radar, but I can happily log another Radar if you don't think it would be redundant. Or, you know, even if it is =)

-tim

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to