【问题标题】:Is there a safe way to cast DWORD_PTR into DWORD?有没有将 DWORD_PTR 转换为 DWORD 的安全方法?
【发布时间】:2017-02-08 08:44:13
【问题描述】:

我实现了这个函数来从 dword_ptr 转换为 dword,但是如果有其他方法可以减少代码,那将不胜感激。 此代码应与 32 位和 64 位窗口兼容 我见过this Question,但答案包含新建和删除操作

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;
}

【问题讨论】:

  • 你的代码绝对没有意义。只需将(DWORD)data; 用于您使用指针的内容?!在安全下是什么意思?将是 x64 中丢失的数据,这取决于 data 中的数据。
  • 如果数据参数包含一个指向大数据的指针,如果它被强制转换,数据将会丢失,所以我必须检查数据是否小于 UNIT_MAX @RbMm
  • 如果您有超过 32 位的数据,则不能将其转换为 32 位而不会丢失数据
  • 在所有情况下unsigned long* value = reinterpret_cast&lt;unsigned long*&gt;(&amp;data); 绝对无意义的代码。使用unsigned long value = (unsigned long)data;
  • 这个没有意义,函数返回一个long,但是需要long long作为输入,显然高位丢失了。

标签: c++ casting mfc dword


【解决方案1】:

有没有将 DWORD_PTR 转换为 DWORD 的安全方法?

整数类型可以相互隐式转换。从不涉及 UB 的意义上说,这种转换是安全的

DWORD_PTR original;
DWORD converted = original;

在 64 位系统上,DWORD 可能小于 DWORD_PTR,在这种情况下,它不能表示 DWORD_PTR 可表示的所有值。因此,如果您进行逆变换,除非高位字节恰好为零,否则您不会得到相同的原始值。此外,如果 DWORD_PTR 表示一个指针值,则将该值转换为 DWORD,然后再转换回 DWORD_PTR,然后再转换为指针,则使用结果指针将不安全。

由于转换正在缩小,编译器可能会生成警告。显式转换使您的意图明确,并且应该消除此类警告:

DWORD converted = DWORD(original);

【讨论】:

  • DWORD_PTR IS A typedef unsigned __int64 ULONG_PTR 它有时用于保存指针,但它不是指针,它可以用作数字,因此如果数字很大,它将在 32 位下被截断
  • 谢谢@user2079303,但我想对警告发出警告
  • 我如何检查它是否在 64 位下不包含指针这种转换会很危险
  • @Abdulrhman 这种转换总是安全的,不管 DWORD_PTR 包含什么。检查您的任何代码是否将 DWORD 转换为指针(直接或通过 DWORD_PTR)。这样的指针使用起来不安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 2016-10-08
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多