title: Objective-C try-catch - why does this compile? And why is the return different building debug vs release?
body: <p>Found this interesting bit of code in an Objective-C category which is used to catch NSExceptions and pass them as NSErrors to Swift code. </p>
  
  <p>What I don't understand about it is:
  1) Why does it even compile? If an exception is thrown, there is never a return value.
  2) Why is the return value different when compiling with debug (optimization level none) and with release (optimization level smallest/fastest)?</p>
  
  <pre><code>- (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error {
     @try {
         tryBlock();
         return YES;
     }
     @catch (NSException *exception) {
         NSMutableDictionary *userInfo = [exception.userInfo mutableCopy];
         if (!userInfo) userInfo = [NSMutableDictionary new];
         userInfo[NSLocalizedDescriptionKey] = exception.reason;
         *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:userInfo];
     }
     // Note the missing return value outside the try-catch
   }
  </code></pre>
  
  <p>Invoking the function:</p>
  
  <pre><code>NSError *error;
  BOOL result = [self catchException:^{
      @throw [NSException exceptionWithName:@"Exception" reason:@"WTF?" userInfo:nil];
  } error:&amp;error];
  
  NSLog(@"Result: %@", result ? @"YES" : @"NO");
  </code></pre>
  
  <p>When compiling and running with the Debug scheme, we get:</p>
  
  <pre><code>2017-02-09 10:01:39.695 Compile Test[23129:630118] Result: NO
  </code></pre>
  
  <p>And when doing the same with the Release scheme:</p>
  
  <pre><code>2017-02-09 10:01:39.695 Compile Test[23129:630118] Result: YES
  </code></pre>
  
  <p>So in both cases there appears to be a return value, even though there is no returned value outside the try-catch block, and the return value inside the try-catch is never reached. We're all very confused over here ?!</p>