将指针转换为整数

我正在尝试将现有代码修改为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位计算机上且尽可能干净地工作。任何的想法 ?


万千封印
浏览 1538回答 3
3回答

慕容森

我会说这是现代的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

繁华开满天机

有几个答案指出uintptr_t并#include <stdint.h>称为“解决方案”。我建议,这是答案的一部分,而不是全部答案。您还需要查看消息ID为FOO的函数的调用位置。考虑以下代码和编译:$ cat kk.c#include <stdio.h>static void function(int n, void *p){&nbsp; &nbsp; unsigned long z = *(unsigned long *)p;&nbsp; &nbsp; printf("%d - %lu\n", n, z);}int main(void){&nbsp; &nbsp; function(1, 2);&nbsp; &nbsp; return(0);}$ rmk kk&nbsp; &nbsp; &nbsp; &nbsp; gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk&nbsp;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 ++之间移植。我的评论适用的机会是公平的。
打开App,查看更多内容
随时随地看视频慕课网APP