我是C++的新手,我正在尝试编写一个小的遗留类库,我一直使用它作为x86 for x64。
现在编译器显示了一些警告:
IUnknown* _p;
// warning C4311: 'type cast': pointer truncation from 'IUnknown *' to 'int'
// warning C4302: 'type cast': truncation from 'IUnknown *' to 'int'
virtual int GetHashCode() override
{
return (int)_p;
}
// 1> warning C4311: 'type cast': pointer truncation from 'void *' to 'long'
// 1> warning C4302: 'type cast': truncation from 'void *' to 'long'
void MyMethod(IntPtr hwnd, String^ str)
{
CComBSTR bstrValue = (BSTR)Marshal::StringToBSTR(str).ToPointer();
HRESULT result = SomeClass()->SomeMethod((long)hwnd.ToPointer(), bstrValue);
}其中SomeMethod被定义为
#ifdef _X86_
typedef long CUSTOMHWND;
#else
typedef LONGLONG CUSTOMHWND;
#endif
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SomeMethod(
/* [in] */ CUSTOMHWND hwndOwner,
/* [in] */ __RPC__in BSTR pValue) = 0;如何更改代码以确保x64的安全?
发布于 2019-04-08 11:42:41
https://learn.microsoft.com/en-us/cpp/build/common-visual-cpp-64-bit-migration-issues?view=vs-2019
更多迁移提示:https://learn.microsoft.com/en-us/windows/desktop/WinProg64/migration-tips
发布于 2019-04-08 12:09:10
通常,基于[expr.cast]/4,C风格的
return (int)_p;最后将执行一个
return reinterpret_cast<int>(_p);严格地说,我认为这种情况下的行为实际上是没有具体说明的。根据[expr.reinterpret.cast]/4
指针可以显式转换为任何足以容纳其类型所有值的整型类型。
请注意,标准只在这里指定将指针值转换为足以容纳该指针类型的任何可能值的整数类型的行为。我不知道标准中的任何措辞会指定将指针值转换为太小的整数类型的情况下的行为,这就是您在这里实际上要做的事情,因为int不够大(在MSVC上)不足以表示64位对象指针值。实际上,我曾经听说过的任何编译器都只会生成返回_p包含的地址的32位(假设_p是32位宽)的代码,但是您很可能不应该依赖它。
通常,如果可以的话,我只需避免将指针转换到整数。如果确实需要,请确保使用足够大的整数类型来保存指针值。在这种情况下,std::intptr_t或std::uintptr_t将是我的首选。
尽管如此,函数的名称表明它只是返回一个哈希值,大概是为了标识哈希表中的某个对象。如果这是目标,我建议您只使用std::hash为您计算这样的哈希值,而不是依靠自己对整数值的转换指针:
virtual std::size_t GetHashCode() override
{
return std::hash<IUnknown*>{}(_p);
}让std::hash负责为您获取一个地址的散列。无论目标平台是…,您都可以依赖于它,无论目标平台是什么,做什么都是正确的选择。
https://stackoverflow.com/questions/55572557
复制相似问题