2016-09-21 61 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

回答編輯。 –