为了账号安全,请及时绑定邮箱和手机立即绑定

将指针转换为整数

将指针转换为整数

C++
慕妹3146593 2019-12-12 14:10:51
我正在尝试将现有代码修改为64位计算机。主要问题是在一个函数中,以前的编码器使用void *参数,该参数在函数本身中转换为合适的类型。一个简短的例子:void function(MESSAGE_ID id, void* param){    if(id == FOO) {        int real_param = (int)param;        // ...    }}当然,在64位计算机上,我得到以下错误:error: cast from 'void*' to 'int' loses precision我想更正此问题,以便它仍可在32位计算机上且尽可能干净地工作。任何想法 ?
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

我会说这是现代的C ++方式。


#include <cstdint>

void *p;

auto i = reinterpret_cast<std::uintptr_t>(p);

编辑:


正确的整数类型

因此将指针存储为整数的正确方法是使用uintptr_tor intptr_t类型。(另请参见c99的 cppreference 整数类型)。


这些类型在<stdint.h>C99 中定义,在stdC ++ 11中的命名空间中定义<cstdint>(请参阅C ++的整数类型)。


C ++ 11(及更高版本)版本


#include <cstdint>

std::uintptr_t i;

C ++ 03版本


extern "C" {

#include <stdint.h>

}


uintptr_t i;

C99版本


#include <stdint.h>

uintptr_t i;

正确的铸造工人

在C语言中,只有一个强制转换,而在C ++中使用C强制转换却不受欢迎(因此请不要在C ++中使用它)。在C ++中,有不同的强制转换。reinterpret_cast是此转换的正确转换(另请参见此处)。


C ++ 11版本


auto i = reinterpret_cast<std::uintptr_t>(p);

C ++ 03版本


uintptr_t i = reinterpret_cast<uintptr_t>(p);

C版


uintptr_t i = (uintptr_t)p; // C Version



查看完整回答
反对 回复 2019-12-13
?
当年话下

TA贡献1890条经验 获得超9个赞

有几个答案指出uintptr_t并#include <stdint.h>称为“解决方案”。我建议,这是答案的一部分,而不是全部答案。您还需要查看消息ID为FOO的函数的调用位置。


考虑以下代码和编译:


$ cat kk.c

#include <stdio.h>

static void function(int n, void *p)

{

    unsigned long z = *(unsigned long *)p;

    printf("%d - %lu\n", n, z);

}


int main(void)

{

    function(1, 2);

    return(0);

}

$ rmk kk

        gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \

            -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \

            -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk 

kk.c: In function 'main':

kk.c:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast

$

您会发现在调用位置(中的main())存在问题-将整数转换为没有强制转换的指针。您将需要分析function()其所有用法,以了解如何将值传递给它。function()如果调用被编写,我内部的代码将起作用:


unsigned long i = 0x2341;

function(1, &i);

由于您的编写方式可能有所不同,因此您需要检查调用该函数的要点,以确保使用所示值有意义。别忘了,您可能会发现一个潜在的错误。


另外,如果您要格式化void *参数的值(转换后的格式),请仔细查看<inttypes.h>标题(而不是stdint.h— inttypes.h提供的服务stdint.h,这是不寻常的,但是C99标准指出,标题<inttypes.h>包含标题<stdint.h>和通过托管实现提供的其他功能对其进行扩展),并在格式字符串中使用PRIxxx宏。


另外,我的评论严格适用于C而不是C ++,但是您的代码位于C ++的子集中,该子集可在C和C ++之间移植。我的评论适用的机会是公平的。



查看完整回答
反对 回复 2019-12-13
  • 3 回答
  • 0 关注
  • 478 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信