ptrdiff_t 와 size_t 의 연산에서 이해가 안가는 점입니다

kyagrd의 이미지
2794
points
-1
points

#include <iostream>

int main(void)
{
    using namespace std;

    int p[100];
    int* p1 = p;
    int* p11 = p + 2;
    int* p2 = p + 12;

    ptrdiff_t pd1 = (p2 - p1) * size_t(p11 - p) + (p2-p1) - (p11-p1);
    size_t st1 = 30;

    cout <<"ptrdiff pd1="<<pd1 <<", size_t st1="<<st1 <<endl;
    cout <<"(pd1 < st1)="<<(pd1 < st1) <<endl;
    cout <<"(pd1 - st1)="<<(pd1 - st1) <<endl;
    cout <<"(st1 - pd1)=" <<(st1 - pd1) <<endl;
    cout <<endl;

//  for (size_t i=0; i < pd1 - st1 ; ++i) cout <<i << endl;

    return 0;
}

이 프로그램의 실행 결과는 다음과 같습니다.

ptrdiff pd1=34, size_t st1=30
(pd1 < st1)=0
(pd1 - st1)=4
(st1 - pd1)=4294967292

분명히 크기 비교를 하면 pd1 이 st1 보다 작지 않고 크다고 나오는데 빼기 연산을 하면 완전히 거꾸로 결과가 나옵니다.

이 코드는 그냥 만들어 낸 것이 아니라 실제로 코딩을 하다 보니 저러한 상황이 생겨 루프가 이상하게 도는 것을 발견하게 된 것입니다.

C++ 표준라이브러리 컨테이너에서 size() 멤버함수가 돌려주는 꼴은 size_t 와 같은 unsigned 꼴이고 임의 접근 되풀이개(random access iterator)에서 - 연산을 하면 ptrdiff_t 와 같은 signed 꼴이 나오게 되는데, 이 값들을 가지고 어찌어찌 연산을 하다 보니 저렇게 되더군요.

사용한 컴파일러는 다음과 같습니다.

Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

익명사용자의 이미지

p2-p1 = 12, p11-p =

1
point

p2-p1 = 12,
p11-p = 2,
p11-p1=2,
pd1 = 12 * 2 + 12 - 2 = 34

pd1 < 30 = 34 < 30 = 0
pd1 - 30 = 34 - 30 = 4
30 - pd1 = 30 - 34 = -4 = 0xffffffff(-1) - 3 = 4294967292

이겠네요.

익명사용자의 이미지

p2-p1 = 12, p11-p =

1
point

p2-p1 = 12,
p11-p = 2,
p11-p1=2,
pd1 = 12 * 2 + 12 - 2 = 34

pd1 < 30 = 34 < 30 = 0
pd1 - 30 = 34 - 30 = 4
30 - pd1 = 30 - 34 = -4 = 0xffffffff(-1) - 3 = 4294967292

이겠네요 ㅡㅡ; < 이거 그냥 쓰면 잘리는군요 ^^

kyagrd의 이미지
2794
points

이게 그냥 unsigned 라 그렇게 된거군요.

1
point

음냐 for 문은 웬만하면 signed 형으로 돌려야겠다 -_-;;
--
There's nothing so practical as a good theory.
- Kurt Lewin

댓글 보기 옵션

원하시는 댓글 전시 방법을 선택한 다음 "설정 저장"을 누르셔서 적용하십시오.