首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x64转换后的指针截断

x64转换后的指针截断
EN

Stack Overflow用户
提问于 2019-04-08 11:36:38
回答 2查看 4K关注 0票数 3

我是C++的新手,我正在尝试编写一个小的遗留类库,我一直使用它作为x86 for x64。

现在编译器显示了一些警告:

代码语言:javascript
复制
            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被定义为

代码语言:javascript
复制
#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的安全?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

票数 2
EN

Stack Overflow用户

发布于 2019-04-08 12:09:10

通常,基于[expr.cast]/4,C风格的

代码语言:javascript
复制
return (int)_p;

最后将执行一个

代码语言:javascript
复制
return reinterpret_cast<int>(_p);

严格地说,我认为这种情况下的行为实际上是没有具体说明的。根据[expr.reinterpret.cast]/4

指针可以显式转换为任何足以容纳其类型所有值的整型类型。

请注意,标准只在这里指定将指针值转换为足以容纳该指针类型的任何可能值的整数类型的行为。我不知道标准中的任何措辞会指定将指针值转换为太小的整数类型的情况下的行为,这就是您在这里实际上要做的事情,因为int不够大(在MSVC上)不足以表示64位对象指针值。实际上,我曾经听说过的任何编译器都只会生成返回_p包含的地址的32位(假设_p是32位宽)的代码,但是您很可能不应该依赖它。

通常,如果可以的话,我只需避免将指针转换到整数。如果确实需要,请确保使用足够大的整数类型来保存指针值。在这种情况下,std::intptr_tstd::uintptr_t将是我的首选。

尽管如此,函数的名称表明它只是返回一个哈希值,大概是为了标识哈希表中的某个对象。如果这是目标,我建议您只使用std::hash为您计算这样的哈希值,而不是依靠自己对整数值的转换指针:

代码语言:javascript
复制
        virtual std::size_t GetHashCode() override
        {
            return std::hash<IUnknown*>{}(_p);
        }

std::hash负责为您获取一个地址的散列。无论目标平台是…,您都可以依赖于它,无论目标平台是什么,做什么都是正确的选择。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55572557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档