Little Jay

[C++] for 문을 사용할때 조건식에서 주의해야 할 점(unsigned와 size_type 그리고 overflow) 본문

Univ/Study

[C++] for 문을 사용할때 조건식에서 주의해야 할 점(unsigned와 size_type 그리고 overflow)

Jay, Lee 2022. 2. 17. 17:39

C++을 하다보면 내가 의도하지 않은 대로 컴파일되어 코드가 실행되는 경우가 있다.

개인적으로 생각할 때 for 반복문에서 조건 설정할 때 생각지도 못한 부분에서 실수를 많이 해 여기에 포스팅 해본다.

#include <string>
#include <iostream>
using namespace std;

int main() {
    string s = "aa";
    for (int i = 0; i < s.length() - 3; i++) {
        cout << s << endl;
    }
}

위 코드를 보면 이상이 없는 코드처럼 보일 수 있다. 

그러나 이 코드를 컴파일 시켜보면 aa 가 엄청나게 많이 출력되는 것을 볼 수 있다.

왜 그럴까?

 

이 모든 원흉(?)은 string.length()를 보면 알 수 있다. 

string.size()나 string.size()는 문자열의 개수를 리턴해주는 멤버함수인데, 이 함수의 원형을 보면 아래와 같다.

size_type size() const;
size_type size() const noexcept;
constexpr size_type size() const noexcept;
size_type length() const;
size_type length() const noexcept;
constexpr size_type length() const noexcept;

이제 여기서 우리가 주목해야 할 부분은 size_type이다.

size_t 는 unsigned int 이며, 문자열이나 메모리의 사이즈를 나타낼 때 사용한다. 

typedef unsigned int size_t;

즉, size_t는 unsigned int인 것이다. 

 

이 unsigned가 특이한 이유가 뭐나면, 우리가 계산의 영역에 들어갈 때 unsigned와 계산해야 하는 부분이 있다면,

우리는 그 결과를 unsigned로 계산을 해야 한다.

 

위의 코드에서 s.length()의 값은 2가 된다.

'음, 2-3 == -1이니까 조건식을 들어가지도 않겠구만!' 라고 생각하면 큰 오산이다.

s.length()의 return 값은 unsigned이기 때문에 2-3은 -1이 아닌 4,294,967,295가 되는 것이다.

이러한 경우를 overflow라고 한다.

일반적으로 int는 4byte, 즉 32bit 이기에 -2^31 ~ (2^31 - 1) 즉 –2,147,483,648 ~ 2,147,483,647 의 범위를 갖는다.

반면 unsigned int는 0~2^32 - 1 즉 0 ~ 4,294,967,295의 범위를 가진다.

-1은 unsigned에서 존재하는 영역이 아니기 때문에 0의 그 전의 수, 즉 순환하여 다시 UNSIGNED_MAX가 되버린다.

 

이 부분에 대해서는 'Computer Systems. A Programmer's Perspective 3rd ED, Randal E. Bryant, David R. O'Hallaron' 책에 잘 정리 되어 있어 이 부분의 코드들을 활용해서 다음 포스팅에서 정리해보겠다.

 

 

'Univ > Study' 카테고리의 다른 글

[OS] pthread.h 실행 명령어  (0) 2022.05.10
객체 지향의 원칙들(SOLID)  (0) 2022.03.04
[C++] emplace_back()과 push_back(), 그리고 Clang-Tidy Bug  (0) 2022.02.16
[C++] Attributes  (0) 2022.02.03
Objected-Oriented Programming의 기둥  (0) 2022.01.27
Comments