2016-03-09 166 views
0

我在C的方法是需要一個雙指針作爲參數:我應該避免投射指針嗎?

void method(
    // in/out 
    double *dOne, 
    ...) 

來電者有一個浮動指針

float *fOne; 

什麼是一個很好的方式調用method()fOne

method((double*)fOne, ...); 

是不是最好的,是嗎?

+0

C中沒有方法C只有函數。 –

+2

將'float *'投射到'double *'將不適用於此。根據真正做的事情,也許:'double temp = * fOne;方法(&temp,...); * fOne = temp;'。你可以把它封裝在一個名爲'void fmethod(float * pf)'的函數中;' –

+0

如果函數需要'double *',那麼你需要傳遞一個真正的'double *'。你可以在函數之外轉換/從'float'。 –

回答

2

你不應該投射不同類型的指針。當指向類型有不同的表示時,這種強制轉換根本沒有任何意義。例如,doublefloat可能不具有相同的大小或表示形式,在這種情況下兩種類型之間的指針轉換明顯不正確。

但是,即使你知道的不同類型,具有相同的表示,指針轉換仍然並不安全!由於strict aliasing rule,這樣的轉換可能會由編譯器產生錯誤生成的代碼,因爲編譯器可以自由地假定您不會通過不正確類型的指針訪問給定數據。所以它可能會優化掉部分代碼。

只有安全投任何給定的指針:在相同的限定的類型(*)

  • 向/從指針指向。
  • 指向相同類型但指定了更多限定符(*)的指針。
  • 指向void指針。
  • 空指針。
  • 的指針字節整數類型,如char*uint8_t*

所有其他指向指針轉換指針的情況都是bug,只要訪問指向的數據就會調用未定義的行爲。包括從char*轉換成指向較大類型的指針


(*)限定的類型的裝置,具有限定符如constvolatile存在的類型。例如,從int*轉換爲const int*是安全的,但從來沒有其他辦法。

+0

注意,這也是「安全的」(就你的意思而言)將* char *從char *類型轉換回原始類型。 –

+0

@OliverCharlesworth嗯......從例如'int *'轉換爲'bananas *'然後回到'int *',而不用通過'bananas'指針訪問數據是安全的。爲什麼你會這樣做,但我不知道。 – Lundin

+0

那麼在'char *'的情況下,爲了完成逐字節的操作,明確允許'char *'強制轉換。但在某些時候,你需要回到原來的類型,這也是安全的! –