2

Is size of size_t always equal to the size of void *?

Or maybe there are some exceptions on some platforms/compilers?

1 Answers1

2

Although it's likely, there's no guarantee. If you want an unsigned integer type that is guaranteed to be able to represent a void *, see uintptr_t.

gsg
  • 9,167
  • 1
  • 21
  • 23
  • 2
    `uintptr_t` is *not* guaranteed to be the same size as a pointer. Although I suppose it is even more likely to be the same size than `size_t` is. – Steve Jessop Oct 31 '13 at 18:07
  • 1
    `uintptr_t` (as well as `intptr_t`) are only guaranteed to hold the value of a pointer to `void` (`void *`) (see 7.18.1.4 of the C Standard). – alk Oct 31 '13 at 18:09
  • @SteveJessop You're right, it's guaranteed to be large *enough* (and whatever other voodoo is required to hold any pointer). –  Oct 31 '13 at 18:09
  • 1
    It is guaranteed to be able to represent a pointer, so it must be at least as large: however, it could be larger. So I guess you're right. – gsg Oct 31 '13 at 18:09
  • If `uintptr_t` exists, it can faithfully represent any value of `void *` (i.e. conversion from `void *` to `uintptr_t` and back is the identity mapping) but there's no restriction against `uintptr_t` being larger (i.e. it's possible that there are values of `uintptr_t` not representable in `void *`, or that `uintptr_t` has additional padding bits making it larger than `void *` in storage size). – R.. GitHub STOP HELPING ICE Oct 31 '13 at 18:10
  • @alk Any pointer can be converted to a `void *` and back (implicitly even, in C), so what's the difference? –  Oct 31 '13 at 18:12
  • Now I think about it, there's also the possibility that function pointers aren't representable (wasn't there some old machine with differing representations for function and data pointers?) – gsg Oct 31 '13 at 18:12
  • 1
    @delnan: function pointers cannot – Chris Dodd Oct 31 '13 at 18:12
  • 1
    `uintptr_t` is not guaranteed to be at least as large, either. It could be smaller if for example there are bits in `void*` that the implementation doesn't use. Only valid pointer values need to be losslessly convertible to `uintptr_t` and back, the implementation is not required to let you put any old bit pattern of the right size in to a `void*` and treat it as a pointer. Obviously it would need to be a funny architecture for that to be a sensible decision, since if there exists an integer type the same size as a pointer, you'd almost certainly use it. – Steve Jessop Oct 31 '13 at 18:13
  • @delnan: The necessary casting to `void *` is the difference. `T i; uintptr_t uptr = &i;` is not necessarily the same as `T i; uintptr_t uptr = (void *) &i;` – alk Oct 31 '13 at 18:17
  • 1
    @gsg Yes. DOS programs had various models where the function pointers were 2 or 4 bytes and _independently_ data pointers were 2 or 4 bytes. – chux - Reinstate Monica Nov 01 '13 at 01:45