2016-09-21 64 views
0

我希望计算程序的BSS段和堆段的起点之间的距离,让我有一个这样的程序:指针arithmatic无法编译,GCC说无效的类型转换

$ 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是不合适的。我在互联网上发现了很多例子。

为什么我的代码不能编译?

+0

@ user1810087您删除C++标记不正确。 OP使用g ++,代码是C++(它也会用C语言编译,因为语言是相似的,但问题不在于C)。 – 2501

回答

3

不要总是相信您在互联网上阅读的内容。

想必,你是在一个平台上,其中三分球是64位和int为32位。在这种情况下,从指针到int的转换将失去精度,并且您正在使用正确的标志进行编译以使其成为错误。做得好!

你正在寻找的指针转换为整数类型的类型是uintptr_t。这由标准定义为具有足够的宽度以允许无损转换。

+0

另外,现在,假设mable的区域应该与.bss有任何关系。可能存在差距,并且有一些从mmaped区域分配到bss之上的实现。 – arsv

1

类型从指针转换为应uintptr_t的,这是保证不失去精度,也见fixed width integer types

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

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

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

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

+0

'%d'是打印2指针之间差异的错误说明符。计算不指向相同内存块的2指针之间的差异也是未定义的行为。 – mch

+0

好吧,我使用'%d'因为OP使用它,并且我声明我没有看到任何理由这样做 –

+0

回答编辑。 –