size_t and ptr_diff_t

Discussion in 'C Programming' started by Bob Cassel, Aug 23, 2007.

  1. Bob Cassel

    Bob Cassel Guest

    I have the idea that ptr_diff_t had to be the same size as size_t from
    Plauger's "The Standard C Library," where he states "... It is always
    the signed type that has the same number of bits as the4 unsigned type
    chosen for size_t..." This language would not rule out one being int
    and the other long so long as sizeof(int)==sizeof(long) for the
    implementation.

    Now I can't see anywhere in the standard that would require that, at
    least not directly, and it seems that a size_t of unsigned int and a
    prtdiff_t of long (where int and long are different sizes) would be
    possible. C99 defines SIZE_MAX as being at least 65535, and
    PTRDIFF_MIN/MAX as being at least -/+65535.

    So do size_t and ptr_diff_t have to be the same size (or base type) or
    not?
    Bob Cassel, Aug 23, 2007
    #1
    1. Advertising

  2. "Bob Cassel" <> wrote in message
    news:...
    >I have the idea that ptr_diff_t had to be the same size as size_t from
    > Plauger's "The Standard C Library," where he states "... It is always
    > the signed type that has the same number of bits as the4 unsigned type
    > chosen for size_t..." This language would not rule out one being int
    > and the other long so long as sizeof(int)==sizeof(long) for the
    > implementation.
    >
    > Now I can't see anywhere in the standard that would require that, at
    > least not directly, and it seems that a size_t of unsigned int and a
    > prtdiff_t of long (where int and long are different sizes) would be
    > possible. C99 defines SIZE_MAX as being at least 65535, and
    > PTRDIFF_MIN/MAX as being at least -/+65535.
    >
    > So do size_t and ptr_diff_t have to be the same size (or base type) or
    > not?
    >

    The problem is that size_t is usally the width of the address bus, because
    the biggest object you can hold in memory is all of memory.
    ptrdiff_t has to represent the difference between two pointers, so it must
    be signed. Therefore it needs an extra bit.
    However that is probably inefficient. Most pointers are not character
    pointers anyway. In practise the promise for subtracting very distant
    character pointers is not honoured, and ptrdiff_t is a signed type with the
    same number of bits as size_t.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Aug 23, 2007
    #2
    1. Advertising

  3. Bob Cassel

    Flash Gordon Guest

    Malcolm McLean wrote, On 23/08/07 21:41:
    >
    > "Bob Cassel" <> wrote in message
    > news:...
    >> I have the idea that ptr_diff_t had to be the same size as size_t from
    >> Plauger's "The Standard C Library," where he states "... It is always
    >> the signed type that has the same number of bits as the4 unsigned type
    >> chosen for size_t..." This language would not rule out one being int
    >> and the other long so long as sizeof(int)==sizeof(long) for the
    >> implementation.
    >>
    >> Now I can't see anywhere in the standard that would require that, at
    >> least not directly, and it seems that a size_t of unsigned int and a
    >> prtdiff_t of long (where int and long are different sizes) would be
    >> possible. C99 defines SIZE_MAX as being at least 65535, and
    >> PTRDIFF_MIN/MAX as being at least -/+65535.
    >>
    >> So do size_t and ptr_diff_t have to be the same size (or base type) or
    >> not?


    They are not required to be the same size. In fact, with the minimum
    requirements you specify (which are correct) it would make sense on a 16
    bit system to have size_t as a 16 bit unsigned integer (unsigned int
    probably) and ptrdiff_t a signed 32 bit integer (long probably). The
    same sort of thing applies to a 64 bit system which limits the maximum
    size of a single object to (2^32)-1, which would not be unreasonable.

    > The problem is that size_t is usally the width of the address bus,
    > because the biggest object you can hold in memory is all of memory.


    Historically some systems have limited the largest single object to be
    much smaller than the address bus allows. For example only allowing
    objects up to 64K on an 80286 or 68000 for efficiency reasons.

    > ptrdiff_t has to represent the difference between two pointers, so it
    > must be signed. Therefore it needs an extra bit.
    > However that is probably inefficient. Most pointers are not character
    > pointers anyway. In practise the promise for subtracting very distant
    > character pointers is not honoured, and ptrdiff_t is a signed type with
    > the same number of bits as size_t.


    True. In practical terms I would be very surprised if anyone allocated a
    single object as large as half the size the address bus can allocate, so
    a ptrdiff_t type the same width as the address bus should be fine.
    --
    Flash Gordon
    Flash Gordon, Aug 23, 2007
    #3
  4. On Aug 23, 9:41 pm, "Malcolm McLean" <> wrote:
    > "Bob Cassel" <> wrote in message
    >
    > news:...
    >
    > >I have the idea that ptr_diff_t had to be the same size as size_t from
    > > Plauger's "The Standard C Library," where he states "... It is always
    > > the signed type that has the same number of bits as the4 unsigned type
    > > chosen for size_t..." This language would not rule out one being int
    > > and the other long so long as sizeof(int)==sizeof(long) for the
    > > implementation.

    >
    > > Now I can't see anywhere in the standard that would require that, at
    > > least not directly, and it seems that a size_t of unsigned int and a
    > > prtdiff_t of long (where int and long are different sizes) would be
    > > possible. C99 defines SIZE_MAX as being at least 65535, and
    > > PTRDIFF_MIN/MAX as being at least -/+65535.

    >
    > > So do size_t and ptr_diff_t have to be the same size (or base type) or
    > > not?

    >
    > The problem is that size_t is usally the width of the address bus, because
    > the biggest object you can hold in memory is all of memory.
    > ptrdiff_t has to represent the difference between two pointers, so it must
    > be signed. Therefore it needs an extra bit.
    > However that is probably inefficient. Most pointers are not character
    > pointers anyway. In practise the promise for subtracting very distant
    > character pointers is not honoured, and ptrdiff_t is a signed type with the
    > same number of bits as size_t.


    I think it is highly unlikely that size_t is in any way related to the
    width of the address bus. For example, I can tell my compiler to
    generate 32 bit code or 64 bit code, and size_t is different
    (actually, I think it is a 32 bit unsigned long in one case and a 64
    bit unsigned long in the other case), but the width of the address bus
    is exactly the same.
    christian.bau, Aug 23, 2007
    #4
  5. "Malcolm McLean" <> writes:
    > "Bob Cassel" <> wrote in message
    > news:...
    >>I have the idea that ptr_diff_t had to be the same size as size_t from
    >> Plauger's "The Standard C Library," where he states "... It is always
    >> the signed type that has the same number of bits as the4 unsigned type
    >> chosen for size_t..." This language would not rule out one being int
    >> and the other long so long as sizeof(int)==sizeof(long) for the
    >> implementation.
    >>
    >> Now I can't see anywhere in the standard that would require that, at
    >> least not directly, and it seems that a size_t of unsigned int and a
    >> prtdiff_t of long (where int and long are different sizes) would be
    >> possible. C99 defines SIZE_MAX as being at least 65535, and
    >> PTRDIFF_MIN/MAX as being at least -/+65535.
    >>
    >> So do size_t and ptr_diff_t have to be the same size (or base type) or
    >> not?
    >>

    > The problem is that size_t is usally the width of the address bus,
    > because the biggest object you can hold in memory is all of memory.


    That's commonly true, but the standard doesn't require it, and there
    have been systems where the maximum size of an object is less than all
    of memory. Note that both size_t and ptrdiff_t (note the spelling)
    are meaningful only for single objects. size_t is the result of
    sizeof, which can only be applied to a single object; ptrdiff_t is the
    result of pointer subtraction, which invokes undefined behavior unless
    both pointers point into the same object.

    > ptrdiff_t has to represent the difference between two pointers, so it
    > must be signed. Therefore it needs an extra bit.
    > However that is probably inefficient. Most pointers are not character
    > pointers anyway. In practise the promise for subtracting very distant
    > character pointers is not honoured, and ptrdiff_t is a signed type
    > with the same number of bits as size_t.


    True. There's no explicit requirement in the standard for size_t and
    ptrdiff_t to be the same size, but they commonly are (I've never heard
    of a system where they aren't). It could make sense to make ptrdiff_t
    larger because it "wastes" one bit for the sign, but that's rarely
    done, if ever.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Aug 23, 2007
    #5
  6. Bob Cassel

    Eric Sosman Guest

    Malcolm McLean wrote On 08/23/07 16:41,:
    >
    > The problem is that size_t is usally the width of the address bus
    > [...]


    Why do you keep on making this claim after it's been
    refuted over and over again?

    The machine in front of me at this moment has a 34-bit
    address bus (it's a creaky old machine; the shoemaker's
    children go barefoot). Depending on the compiler options,
    size_t is either 32 or 64 bits wide.

    --
    Eric Sosman, Aug 23, 2007
    #6
  7. Bob Cassel

    Old Wolf Guest

    On Aug 24, 9:54 am, Eric Sosman <> wrote:
    > Malcolm McLean wrote On 08/23/07 16:41,:
    > > [...]

    >
    > Why do you keep on making this claim after it's been
    > refuted over and over again?


    Because that's what trolls do?
    Old Wolf, Aug 23, 2007
    #7
  8. Bob Cassel

    pete Guest

    Malcolm McLean wrote:

    > In practise the promise for subtracting very distant
    > character pointers is not honoured,
    > and ptrdiff_t is a signed type with the
    > same number of bits as size_t.


    There's no promise,
    unless a program stays inside the minimum environmental limits,
    and then the promise is kept.

    N869

    5.2.4.1 Translation limits
    -- 65535 bytes in an object (in a hosted environment only)


    7.18.3 Limits of other integer types
    -- limits of ptrdiff_t
    PTRDIFF_MIN -65535
    PTRDIFF_MAX +65535


    6.5.6 Additive operators
    [#9] When two pointers are subtracted, both shall point to
    elements of the same array object, or one past the last
    element of the array object; the result is the difference of
    the subscripts of the two array elements. The size of the
    result is implementation-defined, and its type (a signed
    integer type) is ptrdiff_t defined in the <stddef.h> header.
    If the result is not representable in an object of that
    type, the behavior is undefined.

    --
    pete
    pete, Aug 24, 2007
    #8
  9. Bob Cassel

    Jack Klein Guest

    On Thu, 23 Aug 2007 14:11:42 -0700, "christian.bau"
    <> wrote in comp.lang.c:

    > On Aug 23, 9:41 pm, "Malcolm McLean" <> wrote:
    > > "Bob Cassel" <> wrote in message
    > >
    > > news:...
    > >
    > > >I have the idea that ptr_diff_t had to be the same size as size_t from
    > > > Plauger's "The Standard C Library," where he states "... It is always
    > > > the signed type that has the same number of bits as the4 unsigned type
    > > > chosen for size_t..." This language would not rule out one being int
    > > > and the other long so long as sizeof(int)==sizeof(long) for the
    > > > implementation.

    > >
    > > > Now I can't see anywhere in the standard that would require that, at
    > > > least not directly, and it seems that a size_t of unsigned int and a
    > > > prtdiff_t of long (where int and long are different sizes) would be
    > > > possible. C99 defines SIZE_MAX as being at least 65535, and
    > > > PTRDIFF_MIN/MAX as being at least -/+65535.

    > >
    > > > So do size_t and ptr_diff_t have to be the same size (or base type) or
    > > > not?

    > >
    > > The problem is that size_t is usally the width of the address bus, because
    > > the biggest object you can hold in memory is all of memory.
    > > ptrdiff_t has to represent the difference between two pointers, so it must
    > > be signed. Therefore it needs an extra bit.
    > > However that is probably inefficient. Most pointers are not character
    > > pointers anyway. In practise the promise for subtracting very distant
    > > character pointers is not honoured, and ptrdiff_t is a signed type with the
    > > same number of bits as size_t.

    >
    > I think it is highly unlikely that size_t is in any way related to the
    > width of the address bus. For example, I can tell my compiler to
    > generate 32 bit code or 64 bit code, and size_t is different
    > (actually, I think it is a 32 bit unsigned long in one case and a 64
    > bit unsigned long in the other case), but the width of the address bus
    > is exactly the same.


    As much as I dislike the idea of standing up for Malcolm, I think his
    meaning is quite logical even if his use of the term "address bus" is
    ill-advised. If you replace that by saying:

    "size_t is usually the smallest unsigned integer type that can hold
    all the bits in a pointer to char", it makes more sense.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Aug 24, 2007
    #9
  10. "Eric Sosman" <> wrote in message
    news:1187906046.696445@news1nwk...
    > Malcolm McLean wrote On 08/23/07 16:41,:
    >>
    >> The problem is that size_t is usally the width of the address bus
    >> [...]

    >
    > Why do you keep on making this claim after it's been
    > refuted over and over again?
    >
    > The machine in front of me at this moment has a 34-bit
    > address bus (it's a creaky old machine; the shoemaker's
    > children go barefoot). Depending on the compiler options,
    > size_t is either 32 or 64 bits wide.
    >

    Usually.
    You can of course implement a compiler with 42 bit pointers on top of a
    32-bit architecture, and have correspondingly weird rules for size_t.
    However it is not normal to do that sort of thing.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Aug 24, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Denis Remezov

    size_t and size_type

    Denis Remezov, Apr 1, 2004, in forum: C++
    Replies:
    9
    Views:
    19,070
    Pete Becker
    Apr 3, 2004
  2. Replies:
    6
    Views:
    6,393
    Greg Comeau
    Oct 19, 2005
  3. Alex Vinokur
    Replies:
    9
    Views:
    784
    James Kanze
    Oct 13, 2008
  4. Zach
    Replies:
    7
    Views:
    2,134
    Keith Thompson
    Nov 15, 2010
  5. Alex Vinokur
    Replies:
    1
    Views:
    574
Loading...

Share This Page