Arithmetic Overflow in Swift & Objective-C

 

최근 Objective-C로 된 소스를 Swift로 바꾸는 작업을 하고 있다. (이젠 거의 막바지라는 것이 믿기지 않는다.)

Objective-C에서는 C와 동일한 타입으로 사용할 수 있었지만, Swift에서는 C의 unsigned char, unsigned int 값들을 UInt8, UInt32로 포팅하여 사용해야 했다.

 

그러던 중 ... ...

 

 

arithmetic overflow

Thread 1: Swift runtime failure: arithmetic overflow

 

이 오류를 만났다.

해당 오류는 반드시 발생하는 것은 아니었다. (로직이 그랬음)

 

에러 문구에서 알 수 있듯이, 산술 오버플로우로 타입에서 처리할 수 있는 값 이상을 넣었기 때문에 발생했다.

 

문제가 있었던 변수는 UInt8 타입으로, 총 0~255까지의 256개의 정수를 처리할 수 있었다. 즉, 음수가 들어오거나 (그럴 일은 없어야 한다.) 256 이상의 수는 처리하지 못하고 overflow가 발생한다는 말이다.

 

근데, 여기서 의문이 생긴다. 왜 Objective-C에서는 해당 overflow가 발생하지 않았을까?

 

찾아본 결과, 이유는 다음과 같다.

 

C 기반의 언어들은 Overflow가 발생할 경우 wrap-around 된다.

뭔소리야?! 싶지만 말 그대로이다.

 

예를 들어보자!

 

 

 

 

예시

var number: UInt8 = 255
number += 1 // overflow !!

Swift의 경우에는 바로 overflow가 발생한다. 

 

 

반면 Objective-C의 경우를 보자.

var number: UInt8 = 255
number += 1
print(number) // 0

overflow가 될 경우 바로 오류가 발생하는 게 아니라 wrap-around되어 0으로 돌아간다.

 

 

Swift가 비교적 안전한 언어기 때문에 깐깐하게 오버플로우를 잡고, return 해주는 것이다.

 

만약 C 기반 언어들처럼 wrap-around가 되게 하고 싶다면 &+, &- &* 등의 연산자를 사용하면 된다.

 

 

 

 

 

 

참고 자료

Overflow Operators
&+ Operator
Are overflow operators less efficient than performing operations that don't result in overflows?

'iOS > Objective-C' 카테고리의 다른 글

[Objective-C] hooking과 method swizzling  (0) 2024.04.18
Objective-C 기초 문법 정리  (2) 2024.02.15