从 uint8_t* 到 uint32_t 的转换无效 - 从 32 位架构迁移到 64 位架构时?

Dan*_*iel 3 c memory type-conversion

我有一个小函数,可以将 32 位架构上的虚拟内存地址转换为物理内存地址:

\n
uint32_t VIRTBASE;\n\nuint32_t getPhysForVirt(void* virt) {\n  uint32_t offset = (uint8_t*)virt - VIRTBASE;\n  return PHYSBASE + offset;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在过去 10 多年里,它的编译和运行没有出现任何问题。

\n

我更改了编译器来为较新的架构构建存储库(现在首次支持 64 位)。

\n

编译失败提示

\n
\n

从 \xe2\x80\x98uint8_t*\xe2\x80\x99 {aka \xe2\x80\x98unsigned char*\xe2\x80\x99} 到 \xe2\x80\x98uint32_t\xe2\x80\x99 {aka \xe2 的无效转换\x80\x98unsigned int\xe2\x80\x99} [-fpermissive]

\n
\n

现在,我理解了该消息,但我不确定使编译没有错误所需的步骤。

\n

我只是确定我不想启用 -fpermissive

\n

P__*_*J__ 5

您使用了错误的类型。C 语言具有用于将指针转换为整数值的特殊类型。

uintptr_t VIRTBASE;

uintptr_t getPhysForVirt(const void * restrict virt) {
  ptrdiff_t offset = (uintptr_t)virt - VIRTBASE;
  return PHYSBASE + offset;
}
Run Code Online (Sandbox Code Playgroud)

如果其余代码按照这个函数的方式编写 - 那么圣诞节你就有很多工作要做。

  • 我怀疑 OP 的调用代码和“PHYSBASE”需要更新才能处理新的返回类型。是的,圣诞节有很多工作。 (3认同)