3

Quoting from http://msdn.microsoft.com/en-us/library/windows/desktop/aa384242%28v=vs.85%29.aspx

Use UINT_PTR and INT_PTR where appropriate (and if you are uncertain whether they are required, there is no harm in using them just in case). Do not cast your pointers to the types ULONG, LONG, INT, UINT, or DWORD.

Can I safely assume that converting all referenced of DWORD to UNIT_PTR in an existing 32 bit Codeline is safe without any side effects?

Is there are other recommended guidelines to port a 32 bit code which has referenced to DWORD through out the codeline?

Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • wait, no, you misunderstood. DO NOT CONVERT ALL `DWORD` to `UINT_PTR`! – Mooing Duck Feb 26 '13 at 19:04
  • @MooingDuck: And why do you think so? Can you please explain? – Abhijit Feb 26 '13 at 19:11
  • 4
    (1) `UINT_PTR` is to be used _if and only if_ you need to store a pointer in an integer type variable. Otherwise use a integer, or a pointer. (2) `UINT_PTR` will sometimes be 32bit, sometimes 64bit, most of the time, you just don't need that. (3) Since it breaks binary compatability and portability, depending on how you did your IO, it may make your data non-portable. – Mooing Duck Feb 26 '13 at 19:19

3 Answers3

6

This is too crude. Just let the compiler do the work for you, enable warning 4302 so it will tell you when a pointer value gets truncated. Put the #pragma in a good place, the pre-compiled header file would be ideal. Or specify the /we4302 compiler option.

#pragma warning(default:4302)

int main()
{
    int* p = 0;
    long bad = (long)p;    // C4302: 'type cast' : truncation from int* to long
    return 0;
}

The /Wp64 compile option can be useful as well, for a sniff anyway, but it has problems.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • +1: `This is too crude`, but this is sounding the most practical solution to me – Abhijit Feb 26 '13 at 19:53
  • Your answer was the most practical. I have added /we4302 in my build system and now struggling to fix the legacy sins – Abhijit Mar 02 '13 at 15:25
2

You only need to use INT_PTR or UINT_PTR if you are planning to store a pointer in the variable (including various forms of HANDLE). If it's just a regular integral value, then it won't matter.

I expect that you'll get at least some warnings for "trying to store a larger type in a smaller type" if you blindly translated all DWORD to UINT_PTR. [That is, when you compile the code for 64-bit, as in 32-bit code, the type UINT_PTR is the same as DWORD so you may not get any warnings in that case].

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • So can I safely conclude that I may convert all referenced of DWORD to UINIT_PTR? – Abhijit Feb 26 '13 at 19:03
  • I thought that's what I answered: You shouldn't just blindly convert EVERY `DWORD` to `UINT_PTR`, because there are probably cases where a `DWORD` is exactly the right thing. Of course, without seeing your code, I don't know, since I don't know what you are using `DWORD` for. In nearly all cases, however, a DWORD is not used to store a pointer, so if nothing else, you will use more space for your data than necessary. – Mats Petersson Feb 26 '13 at 19:06
  • `so if nothing else, you will use more space for your data than necessary`, Yes I understand. But as you said, DWORD is used for lot many things apart from to store a pointer, IF I blindly convert all DWORD to UNIT_PTR, apart from using more space, would there be other implication? – Abhijit Feb 26 '13 at 19:10
  • Breaks binary compatibility and portability, and depending on how you do IO, that could be bad. Also, it's a bad idea because it's confusing. That's like taking an elephant and telling everyone it's a Giraffe. `UINT_PTR` tells everyone that this is a pointer but you need to temporarily do numeric things with it. – Mooing Duck Feb 26 '13 at 19:20
  • Why do you think you need to convert every `DWORD` to `UINT_PTR`? Yes, it may seem like an easy solution, but most likely, it's not the RIGHT solution. If your code is large (say, more than 10000 lines), then you will probably have to work a bit to convert it to 64-bit. But unless you are often storing pointers in `DWORD` variables, it shouldn't be too bad. Do I know how much of your code stores pointers in `DWORD` variables, no, I don't. Hopefully not that much, since it's a bad thing to do in the first place [although sometimes necessary]. – Mats Petersson Feb 26 '13 at 19:29
1

To add on @MatsPetersson answer -

The reason DWORD is widely used to hold addresses is that it matches the pointer size on 32-bit architecture.

Best practice is to use dedicated types for variables holding addresses. That's what UINT_PTR & INT_PTR are for - they are correct for both 32 and 64-bit targets since their definition is set correctly according to compilation target. Actually, you can browse the MS headers and see for yourself the actual primitive types that these types correspond to.

Whenever the variable is used for data other than address, actual type should be defined according to the stored data and normally won't depend on underlying computer architecture - DWORD will remain DWORD, WORD will remain WORD etc.

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85