2010-05-01 115 views
2

某處的代碼行,我碰到這個結構...這個C++構造是做什麼的?

//void* v = void* value from an iterator 
int i = (int)(long(v)) 

可以在此contruct起到什麼可能的目的是什麼?

爲什麼不簡單地用int(v)代替?爲什麼首先投到long

+5

小心給更多的上下文? – 2010-05-01 21:55:57

+0

@James Morris:我認爲這是所有需要的信息......我從容器中得到'void *'值,而這些void *值實際上是整數(它們被當作void *)。現在我想要那些整數回來。我已經在問題中提到過了。 – Moeb 2010-05-01 21:59:01

+2

我寧願問他們爲什麼要在一個表達式中混合使用兩種不同的表達式:) – AnT 2010-05-01 22:04:58

回答

8

它最有可能使警告無聲。假設32位體系結構的sizeof(int)< sizeof(long)和sizeof(long)== sizeof(void *),你可能會得到一個警告,如果你將一個void *一個void *,只要你不截斷。然後,你會得到一個警告,將一個long賦值給一個int(可能的截斷),然後通過從long明確地轉換爲int來移除它。

不知道編譯器很難說,但我已經看到了防止警告所需的多步轉換。爲什麼不嘗試將構造轉換爲您認爲應該的內容,並查看編譯器所說的內容(當然,如果您使用相同的編譯器和相同的警告級別,只會幫助您計算出原始程序員的想法因爲他們是)。

+0

@Len Holgate:我正在使用的機器上sizeof'void * = 8,long = 8,int = 4'。 – Moeb 2010-05-06 13:22:50

3

它確實是eeevil。

在大多數體系結構中,指針可以被認爲是另一種類型的數字。在大多數體系結構中,long與指針的位數相同,因此long值與指針之間有1對1映射。但違規行爲,特別是第二條規則,並不罕見!

long(v)reinterpret_cast<long>(v)的別名,它不承擔任何保證。除非您的ABI規範另有說明,否則不適合用於任何目的。

但是,無論出於何種原因,編寫該代碼的人更喜歡intlong。所以他們再次交叉他們的手指,並希望沒有必要的信息被扔在可能丟失在intlong劇組中的位中。

這樣做的兩個用途是創建一個唯一的對象標識符,或試圖以某種方式打包指針,否則某些算法不支持指針。

  • 不透明標識符可以是void*,因此不需要轉換爲整型。
  • 「從指針中提取整數」(例如除法操作)總是可以通過減去一個基指針來獲得類型爲ptrdiff_t的差異,通常是long
+0

在GUI代碼中看到它。 – 2010-05-01 22:21:44

+2

單獨爲邪惡+1。 – GManNickG 2010-05-01 22:25:42

+0

或者它可能不會做壞事。例如,'void *'可能是一個不透明的用戶數據項,它正在通過函數傳遞給回調函數,例如線程啓動數據。給調用者最大的靈活性是一個'void *'。調用者可能會傳遞一個整數值,並且可能希望在調用的另一端獲得它。在Windows上,你最近可能會將用戶數據視爲'ULONG_PTR',這很可能會將對cast的需求移除爲'long',但是仍然需要將該類型轉換爲'int',並且在這種情況下,它是不是邪惡的,但設計可能會更好。 – 2010-05-01 23:34:45