2014-09-02 121 views
0

我讀過將指向一個類型的指針指向另一個指向另一個類型的指針是非法的;例如,在本書中:指針轉換

C How To Program 7 ed。 PAG。 299

常見編程錯誤7.7 分配一個類型的指針 指針另一種類型的,如果兩者都不是類型爲void *的是一個語法錯誤 。

或在此URL

但豪爾在C11標準被寫入:

一個指向對象類型可被轉換成一個指針指向一個不同 對象類型。如果生成的指針不正確 爲引用類型對齊,行爲是未定義的。 否則,當再次轉換時,結果應該等於 與原始指針。

所以我明白,只有在存在對齊問題的情況下,行爲纔是未定義的。

事實上,像GCC 4.8或CL 2013這樣的編譯器只會發出不兼容指針類型賦值的警告。

void指針不存在該異常。

所以:

int a = 10; 
float b = 100.22f; 

int *p_a = &a; 
float *p_f = &b; 

p_a = p_f; // NOT ILLEGAL but WARNING 
p_f = p_a; // converted back again. it still works 

void *v_p = p_a; // NOT ILLEGAL NO WARNING 
p_a = v_p; // converted back again. it still works 

我理解的呢?或者我錯過了什麼?

P.S. 也可以任何人給我看一個「對齊問題」的例子嗎?

+0

也許你可以告訴我們這些「很多書」是什麼,他們實際上說了些什麼?你使用的是什麼版本的gcc,以及它給出了什麼樣的警告。並且告訴我們你在調整方面所做的研究,以及你不瞭解哪些部分。 – Useless 2014-09-02 12:06:36

+0

@Useless,我不明白是否將指針指向指向另一個類型的指針的類型是LEGAL或NOT,與void *一樣。對於標準,它似乎明白它是合法的...... – xdevel2000 2014-09-02 12:23:41

+0

如果本書說分配指向另一種不同類型的指針是「語法錯誤」,那麼這本書是錯誤的! – Jay 2014-09-02 13:04:58

回答

2

您可以將指針視爲內存中指向數據的偏移量,而不管它是哪種類型。任何標準指針(不是智能指針)都有固定大小,取決於系統(32位或64位)。所以你可以將它們分配給其他的,現代編譯器會警告你有關危險的操作,但問題是當你試圖解除引用不兼容類型的指針時。提領時,應用程序查找對應尖型的字節數,所以在反引用的pB下面的例子

int b = 10; 
int* pB = &b; 
double* pA = pB; 

你會得到10(INT的大小爲4個字節),並在解引用爸爸,你會得到垃圾或者因爲接下來的4個字節(double是8個字節)可能是爲另一個變量分配的內存空間。

結論:在將指針類型分配給彼此時跟蹤指針類型,特別是如果您間接指定它們,則使用void *作爲中介。 指針賦值的合法性或非法性是編譯器的問題,舊的不會警告你。分配給void *不被認爲是「非法的」,可能是因爲它是通用的,不可指向的指針類型(它具有未定義的引用大小,並且該限制是c語言限制),所以不能像上面的示例那樣收到錯誤。