6

why does following code do not throw an arithmetic error at runtime -> 1/0;

printf("in start\n");
int i=1/0;
//int o=i;
NSString* myString = [@(i) stringValue];
printf("%s", [myString UTF8String]);
printf("\nafter start\n");

Console:

in start
-1074745488
after start
mcfly soft
  • 11,289
  • 26
  • 98
  • 202

2 Answers2

10

It doesn't throw an error as it is pure C — and C doesn't know how to throw errors.


if you enter the objective world of Objective-C like

NSDecimalNumber *i = [NSDecimalNumber decimalNumberWithDecimal:[@(1) decimalValue]];
NSDecimalNumber *o = [NSDecimalNumber decimalNumberWithDecimal:[@(0) decimalValue]];

NSDecimalNumber *x = [i decimalNumberByDividingBy:o];

you will see

*** Terminating app due to uncaught exception 'NSDecimalNumberDivideByZeroException', reason: 'NSDecimalNumber divide by zero exception'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff870cf50c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff8abd076e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff870cf3bd +[NSException raise:format:] + 205
    3   Foundation                          0x00007fff8a476ec5 -[NSDecimalNumberHandler exceptionDuringOperation:error:leftOperand:rightOperand:] + 242
    4   Foundation                          0x00007fff8a475cab _checkErrorAndRound + 57
    5   Foundation                          0x00007fff8a47606c -[NSDecimalNumber decimalNumberByDividingBy:withBehavior:] + 159
    6   devisonByZero                       0x0000000100000e54 main + 484
    7   libdyld.dylib                       0x00007fff8aaa45c9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

But you actually can decide, what happens:

NSDecimalNumberHandler *h = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                   scale:1
                                                                        raiseOnExactness:NO
                                                                         raiseOnOverflow:NO
                                                                        raiseOnUnderflow:NO
                                                                     raiseOnDivideByZero:NO];

NSDecimalNumber *x = [i decimalNumberByDividingBy:o withBehavior:h];

x will be NaN now.


But apple also provides C-types that are aware of calculation errors: NSDecimal

NSDecimal one = [@1 decimalValue];
NSDecimal zero = [@0 decimalValue];
NSDecimal result;
NSCalculationError error = NSDecimalDivide(&result, &one, &zero, NSRoundPlain);
switch (error) {
    case NSCalculationNoError:
        NSLog(@"result: %@", [NSDecimalNumber decimalNumberWithDecimal:result]);
        break;
    case NSCalculationDivideByZero:
        NSLog(@"division by 0");
        break;
    default:
        NSLog(@"some calculation error");
        break;
}
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
3

Why should it?

XCode gives you the warning Division by zero is undefined. That should be a big enough sign for you.


Note:

C# doesn't always throw an exception.

C++ send a signal, which if not handled, just kills your process.


There's an amazing explanation in the C++ thread:

Dividing by zero is a logical error, a bug by the programmer. You shouldn't try to cope with it, you should debug and eliminate it.

Fix the hole in the wall rather than trying to hang a picture over it.

Community
  • 1
  • 1
Lord Zsolt
  • 6,492
  • 9
  • 46
  • 76
  • Why should it not ? Every language I know does. I saw the warning in XCode of course, but my question was why it doesn't throw the error. Obviously it doesn't and will just give any random number, which can be very confusing. – mcfly soft Feb 14 '15 at 11:10
  • If the divisor is not known on runtime, as it is read from any input, the compiler can't warn. – vikingosegundo Feb 14 '15 at 12:16
  • That's why you add an if (value != 0) which is MUCH easier and less resource intensive than catching an exception. – Lord Zsolt Feb 14 '15 at 12:18
  • 2
    that depends on the use case. there might be reasons that a developers prefer the app to crash with invalid input. In test environments for example. – vikingosegundo Feb 14 '15 at 12:22
  • You just contradicted yourself with these 2 comments... Do you want to be warned to prevent it or do you want to let the program crash? – Lord Zsolt Feb 14 '15 at 12:38
  • no, sometimes it is useful to have a app crashing with an exception and a stack trace than keep on working on undefined data. I said nothing about catching the error. – vikingosegundo Feb 14 '15 at 13:00
  • And a unit test in a test target will catch it and report back to me. – vikingosegundo Feb 14 '15 at 13:01
  • Well C doesn't have that functionality and Objective-C is based on it so yeah. – Lord Zsolt Feb 14 '15 at 13:05
  • I have now idea what your last comment wants to tell me. Anyway, your answer just refers to a warning, I just show, that in real world scenarios it most likely will not appear. If you feel you should defend your answer by finding contradictions in my comments rather than fix your answer that is your decision. – vikingosegundo Feb 14 '15 at 13:13
  • What do you not understand? C doesn't throw an exception in this case, your program would just crash. (As you've said in your answer). Objective-C is based on C. – Lord Zsolt Feb 14 '15 at 13:25
  • And I say: there might be cases where a crashing program is the preferred. So what don't u understand? – vikingosegundo Feb 14 '15 at 13:38
  • I have to agree to vikingosegundo, but I also understand that technically C can't throw an error. Das, that ObjectiveC which is a layer up to C ( from my understanding ) is not able to handle exceptions. I also have to say, I am a newby in ObjectiveC. – mcfly soft Feb 14 '15 at 19:33
  • at Lord Zsolt. Thanks a lot. I 1+ your answer, because your answer is good, but accepted answer of vikingosegundo, because it gives me a better understanding. – mcfly soft Feb 14 '15 at 19:36