我正在從遺留代碼中刪除gcc警告。如何解決:「轉換爲C代碼中的不同大小的整數的指針」警告?
是否有可能通過抑制鑄字「轉換爲指針從大小不同的整數」警告:
example:
some_struct *ptr = func() // func() returns an integer.
是否有人可以指導我如何解決這樣的GCC警告?
我正在從遺留代碼中刪除gcc警告。如何解決:「轉換爲C代碼中的不同大小的整數的指針」警告?
是否有可能通過抑制鑄字「轉換爲指針從大小不同的整數」警告:
example:
some_struct *ptr = func() // func() returns an integer.
是否有人可以指導我如何解決這樣的GCC警告?
首先,如果您可以修復func
(允許修改其來源),然後修復它。如果它的計算可以用指針完成,那麼用指針和返回指針來完成它們。有時候有理由將地址作爲整數處理(例如,處理特殊代碼中的對齊問題)。在這種情況下,請將func
更改爲使用uintptr_t
類型(在stdint.h
中定義)。它被設計用於在必要時將指針視爲整數。 (也有intptr_t
如果由於某種原因有符號算術更好,但我通常會發現無符號的uintptr_t
不那麼麻煩。)func
最好在返回時將uintptr_t
轉換爲指針,因此func
的返回類型將是一個指針(可能是some_struct
或void
)。
如果您無法修復func
,那麼您可以使用強制轉型告訴編譯器您打算執行正在執行的轉換。然而,這個特定的錯誤信息告訴你,你不僅僅是將一個整數轉換爲一個指針,而是將一個大小的整數(例如四個字節)轉換爲另一個大小的指針(例如八個字節)。很可能這個代碼最初是爲func
返回的整數類型與指針類型具有相同大小的系統編寫的,但您現在正在指針類型大於或小於整數大小的系統上進行編譯。
在這種情況下,您必須確保func
執行的計算適用於新體系結構。如果它只返回一個32位的數值,它是否總是保持正確的值?也就是說,丟失的高32位不會丟失什麼? func
應該計算的地址不會超過它使用的整數類型的最大值嗎?如果func
正在使用帶符號的整數類型,請考慮符號位。
如果您確定func
返回的值是正確的,那麼您可以使用明確的轉換,例如:some_struct *ptr = (some_struct *) (intptr_t) func();
。
我的gcc沒有給出你引用的警告。這也會很奇怪,因爲代碼中沒有強制轉換。
我得到警告
assignment makes pointer from integer without a cast
注意 「不進行強制轉換」 部分。因此,你可以讓GCC無聲鑄造(不改變行爲):
some_struct *ptr = (void*)func();
然後,你會得到你的警告(「劇組到指針由大小不同的整數」)當且僅當func
返回類型不適合爲地址。這可以通過將func()
額外地鑄造成合適的整數類型來消除,例如, intptr_t
:
some_struct *ptr = (void*)(intptr_t)func();
這一切你真的想錯了大小的整數轉換爲指針的假設下。重新編寫代碼可能是一個更好的主意。
這裏有兩種可能性:
func
是鑄造實際指向的整數;它稍後用作指針。func
返回存儲在指針中的整數; ptr
稍後將轉換爲整數並用作整數。在第一種情況,從func
返回值將丟失信息,並且潛在地導致崩潰或更糟,如果int
比數據指針的大小,這將是在大多數64-bit memory models(包括Windows較小和Linux)。在這種情況下,您應該將退貨類型func
更改爲intptr_t
;見Using intptr_t instead of void*?和Why/when to use `intptr_t` for type-casting in C?。
在第二種情況下,它不是一個問題,而是處理通過intptr_t
:some_struct *ptr = (some_struct *)(intptr_t)func();
和更高版本int value = (int)(intptr_t)ptr;
投遞的字節順序問題。有關此問題的討論,請參閱GLib Type Conversion Macros。
爲什麼你想要將一個整數放入一個結構指針? – Jay 2012-08-03 13:40:59
這是可能的,但是這種情況是正確的解決方法。 – 2012-08-03 13:41:53
是否存在「輸出」差異的重載?(不是輸入參數) – 2012-08-03 13:43:19