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

kyagrd의 이미지

#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 = 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 = 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의 이미지

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

--
There's nothing so practical as a good theory. - Kurt Lewin
"하스켈로 배우는 프로그래밍" http://pl.pusan.ac.kr/~haskell/

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.