3

I am writing a custom assertion macro. It call this function when assertion failed.

void _XLCAssertionFailedCritical(NSString *format, ...) __attribute__((noreturn));
void _XLCAssertionFailedCritical(NSString *format, ...)
{
    va_list ap;
    va_start(ap, format);

    NSException *ex = [NSException exceptionWithName:NSInternalInconsistencyException reason:[[NSString alloc] initWithFormat:format arguments:ap] userInfo:nil];

    va_end(ap);

    [ex raise];
}

but it have a warning

XLCAssertion.m:69:1: Function declared 'noreturn' should not return

change [ex raise] to @throw ex fixed the warning.

But the warning won't exist if -[NSException raise] have noreturn attribute. In fact, none of the methods in NSException have noreturn attribute.

I understand that [ex raise] may still return if ex is nil. In this case, noreturn attribute shouldn't be allowed on instance method at all. But [NSException raise:format:] always raise an exception (unless someone swizzled it...) so noreturn should be used to help compiler analyze unreachable code and check method does not return.

This just make me think that raise and its family on NSException should never be used. But I can't find documentation/guide about that. Did I missed something?

Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
  • One workaround is [Jeffery Thomas's answer to "+\[NSException raise:format:\] as the last statement in a method"](http://stackoverflow.com/a/10401916/603977): use `@throw` instead. Since this is a compiler directive, the analyzer knows that it is terminal. – jscs Aug 06 '15 at 06:21

0 Answers0