【问题标题】:Cast int to void*将 int 转换为 void*
【发布时间】:2014-10-14 18:56:05
【问题描述】:

我正在尝试从 int 创建一个 void*。但是 gcc 总是给我一个警告,我不能将 int 转换为 void*。这是我的代码:

#define M_TABLE_SIZE 64*1024
static const void* M_OFFSET = M_TABLE_SIZE;

我已经尝试过(void*)M_TABLE_SIZE,但是我得到一个错误,我不能使用* 运算符。

将 int 转换为 void* 的正确方法是什么?

【问题讨论】:

标签: c pointers gcc


【解决方案1】:

这个

static const void* M_OFFSET = (void*)M_TABLE_SIZE;

扩展到

static const void* M_OFFSET = (void*)64*1024;

由于 gcc 编译您正在执行 void* 和 int (1024) 之间的算术运算。将您的定义放在括号内:

#define M_TABLE_SIZE (64*1024)

现在,你可以这样做了:

static const void* M_OFFSET = (void*) M_TABLE_SIZE;

没有问题。将您的 #define 放在括号中以避免这种意外总是一个好习惯。

除非你在那个值上有一个有效的地址,否则你会在尝试使用那个指针时调用未定义的行为。因此,请确保您了解自己在做什么!

【讨论】:

  • 我想另一个重要的事实是强制转换运算符比乘法运算符具有更高的优先级
  • @BlueMoon 非常感谢!我以为 gcc 会根据我的定义生成 65536,但我错了。
【解决方案2】:

对于相当新的编译器(支持 C99),您不应将地址存储或表示为纯 int 值。如果你真的需要这种诡计,那么考虑一种专用类型,它们是intptr_t 和uintptr_t。参考 N1570 7.20.1.4/p1(能够保存对象指针的整数类型):

下面的类型用属性指定有符号整数类型 任何指向 void 的有效指针都可以转换为这种类型,然后 转换回指向 void 的指针,结果将比较相等 指向原始指针:

intptr_t

以下类型指定无符号整数类型 任何指向 void 的有效指针都可以转换为此类型的属性, 然后转换回指向void的指针,结果将比较 等于原来的指针:

uintptr_t

这些类型是可选的。

你的情况可能是:

#include <stdint.h>

#define M_TABLE_SIZE ((intptr_t) (64*1024))
static const void* M_OFFSET = (void *) M_TABLE_SIZE;

【讨论】:

    【解决方案3】:

    首先,您使用的是定义,它不是变量。 预处理器将替换您的代码:

    static const void* M_OFFSET = 64*1024;
    

    这不太可能是你想要做的。

    您可以声明一个 const int 变量并将其引用转换为 void*。

    【讨论】:

    • 预处理器绝对不会进行算术运算
    • 你是对的!感谢您指出了这一点。刚刚编辑。但是,我相信即使定义是针对“65536”,这也不是@kaetzacoatl 想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2019-11-19
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多