최근 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 |