6

As described in this MSDN article, Microsoft has these two type annotations to declare native pointers on different architectures. However, on the second line:

On a 32-bit system, a pointer declared with __ptr64 is truncated to a 32-bit pointer. On a 64-bit system, a pointer declared with __ptr32 is coerced to a 64-bit pointer.

This sounds to me like the declaration doesn't matter; if the architecture overrides the declaration of __ptrXX to be the default anyways, what's the point of marking __ptrXX in the first place?

I see that this answer says that it's for interop, but if the declarations are essentially overridden as above, how does that help with interop?

Community
  • 1
  • 1
Cannoliopsida
  • 3,044
  • 5
  • 36
  • 61

1 Answers1

4

There's a big difference between declaring and assigning a 32-bit pointer and actually using it. In other words, dereferencing the pointer. If you do that in a 64-bit process then there is no other option but to sign-extend it to a 64-bit pointer. Which is what "coerced" means. That may work by accident, but you'd have to be pretty lucky. It just doesn't make sense to try.

The point of declaring a __ptr32 is as described in that linked answer, it only makes sense when you interop with a 32-bit process. Which uses 32-bit pointers. It is not common.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • That the coercion doesn't happen immediately and is actually avoided, makes this clear. I'm curious and know little about interop: do 32-bit programs every practically interop with 64-bit programs? I.e. does the reverse ever happen, or is the __ptr64 just there for symmetry/having the theoretical possibility? – Cannoliopsida Jul 22 '13 at 19:36
  • According to [this](http://blog.aaronballman.com/2013/05/msvc-pointer-type-attributes/), a `__ptr32` is always 32 bits, and a `__ptr64` is always 64 bits, regardless of the target platform. 32-bit programs only use the low 32 bits of a `__ptr64`, dynamically truncating the 64-bit value into a 32-bit value. Weirdly, however, the compiler doesn't consider `T* __ptr32` and `T* __ptr64` distinct types, although it does recognise the size difference. – Justin Time - Reinstate Monica May 30 '16 at 19:55