-1

I implemented this function to convert from dword_ptr to dword but if there is other way with less code that will be appreciated. this code should be compatible with 32bit and 64bit windows I have seen this Question but the answer contains new and delete operations

inline unsigned long Convert_to_DWORD(unsigned long long data)
{
    //typedef unsigned __int64 ULONG_PTR
    //typedef ULONG_PTR DWORD_PTR
    //typedef unsigned long       DWORD;
    assert(UINT_MAX > data);
    unsigned long* value = reinterpret_cast<unsigned long*>(&data);
    return *value;
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Abdulrhman
  • 109
  • 2
  • 10
  • your code absolute senseless. simply use `(DWORD)data;` for what you use pointers ?! and what mean under safe ? are will be data lost in x64 depended from what data in `data` – RbMm Feb 08 '17 at 08:50
  • if the data param includes a pointer to a large data the data will be lost if it will be casted so I must check if the data less than UNIT_MAX @RbMm – Abdulrhman Feb 08 '17 at 08:54
  • if you have more that 32bit data, you can not cast it to 32bit without lost data – RbMm Feb 08 '17 at 08:56
  • in all case `unsigned long* value = reinterpret_cast(&data);` absolute senseless code. use `unsigned long value = (unsigned long)data;` – RbMm Feb 08 '17 at 08:57
  • @RbMm yes that is the problem sometimes DWOD_PTR would be used as a pointer – Abdulrhman Feb 08 '17 at 08:58
  • 2
    This makes no sense, the function returns a long, but takes a long long as input, obviously the high part is lost. – Constantine Georgiou Feb 08 '17 at 08:59
  • in this case `DWOD_PTR would be used as a pointer ` why you want cast it to dword ? use as dword_ptr – RbMm Feb 08 '17 at 09:00
  • @ConstantineGeorgiou this is just a trial to find some solution to convertion problem between this two types in comments you can find why I used log long and log – Abdulrhman Feb 08 '17 at 09:02
  • typedef unsigned __int64 ULONG_PTR ; typedef ULONG_PTR DWORD_PTR ; typedef unsigned long DWORD; – Abdulrhman Feb 08 '17 at 09:03
  • @RbMm return static_cast(data); it could be so but I just wrote to be more clear – Abdulrhman Feb 08 '17 at 09:08
  • If this were possible, you'd have found a way to store an infinite amount of data into a `DWORD`. Don't fight logic. Simply accept it. – IInspectable Feb 08 '17 at 19:55

1 Answers1

2

Is there a safe way to cast DWORD_PTR into DWORD?

Integer types are implicitly convertible to each other. Such conversion is safe in the sense that there is no UB involved

DWORD_PTR original;
DWORD converted = original;

On a 64 bit system DWORD may be smaller than DWORD_PTR, in which case it cannot represent all the values representable by DWORD_PTR. Therefore if you do the inverse conversion, you do not get the same original value back unless the high order bytes happened to be zero. Furthermore, if DWORD_PTR represented a pointer value, then converting the value to DWORD then back to DWORD_PTR then back into a pointer then using the resulting pointer would not be safe.

Since the conversion is narrowing, a compiler might generate a warning. An explicit conversion makes your intention unambiguous and should silence such warning:

DWORD converted = DWORD(original);
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • DWORD_PTR IS A typedef unsigned __int64 ULONG_PTR it sometimes used to save pointers but it is not a pointer it could be used as a number so if the number is huge it will be truncated under 32bit – Abdulrhman Feb 08 '17 at 09:23
  • thank you @user2079303 but I want to ger red of the warning – Abdulrhman Feb 08 '17 at 09:36
  • how can i check if it under 64bit does not include pointer this conversion will be dangerous – Abdulrhman Feb 08 '17 at 09:42
  • @Abdulrhman This conversion is always safe, regardless of what DWORD_PTR contains. Check if any of your code converts a DWORD to a pointer (either directly or through DWORD_PTR). Such pointer is not safe to use. – eerorika Feb 08 '17 at 09:45