指针算术编译失败,gcc 说类型转换无效

Pointer arithmatic failed to compile, gcc says invalid type conversion

我想计算程序的 bss 部分和堆部分开始之间的距离,所以我有这样的程序:

$ cat 1.cpp

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int empty;//bss
int main()
{
  char*p=(char*)malloc(0);
  printf("%d\n",(int)p-(int)&empty);
  return 0;
}

当我使用以下代码编译该代码时:

$ g++ 1.cpp

错误是:

1.cpp: In function ‘int main()’:
1.cpp:8:22: error: cast from ‘char*’ to ‘int’ loses precision [-fpermissive]
   printf("%d\n",(int)p-(int)&empty);
                  ^
1.cpp:8:30: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
   printf("%d\n",(int)p-(int)&empty);
                          ^

我不认为将 int* 转换为 int 是不合适的。我在互联网上找到了很多这样做的例子。

为什么我的代码无法编译?

从指针转换为的类型应为 uintptr_t,保证不会丢失精度,另请参阅 fixed width integer types

如果你坚持使用printf,那么你需要找到合适的格式化程序,因为那不是固定的。否则,使用:

std::cout << reinterpret_cast<uintptr_t>(p);

不要总是相信你在网上看到的东西。

据推测,您所处的平台的指针是 64 位的,而 int 是 32 位的。在这种情况下,从指针到 int 的转换会失去精度,并且您正在使用正确的标志进行编译以使其成为错误。做得好!

您要将指针转换为整数类型的类型是 uintptr_t。这由标准定义为具有足够的宽度以允许无损转换。

你可能想要p-reinterpret_cast<char*>(&empty)

但我看不出有任何理由需要计算这两个地址之间的距离。 (并且是@mch 指出的未定义行为)