2010-04-22 31 views
0

當我們編寫一個我們創建的庫的新版本(用C語言)時,我們禁止將結構體的大小改爲更小。爲什麼?爲什麼在替換舊庫時不能減小結構的大小?

具體來說,

版本1具有這樣的:

struct foo { 
    int a; 
    int b; 
} 

版本2具有這樣的:

struct foo { 
    char a; 
    char b; 
} 

,我們單獨從聲明的結構定義,這樣才能使圖書館用戶無法訪問該結構的成員。

+2

爲什麼不問問誰制定規則? – 2010-04-22 08:54:06

+0

誰制定了這條規則?我從來沒有聽說過它,尤其是如果你只向用戶公開不透明句柄/ void指針。 – nos 2010-04-22 09:23:51

+0

@ nos,Neil:參考http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html – solotim 2010-04-22 09:35:13

回答

3

它很難猜測,因爲可能有一些或多或少有效的原因可能都與試圖向後兼容,並避免在更新時更新所有程序。

結構可以是(AB)在許多方面使用,例如人們可以有指向一個struct內,而不是通過名字訪問結構成員可以使用指針閒逛:

struct { 
    int a; 
    int b; 
    int c; 
} s; 

,如果有人訪問與結構

struct s mys; 
... 
int *p = &mys.a; ++p; ++p; *p = 3; 

這將打破,如果結構有變小

作爲一個例子的Windows(以其悠久的歷史知向後兼容性頭痛)通常具有結構的大小作爲結構中的第一個成員,然後應用程序會首先讀取該值以猜測它們正在處理的結構版本,這當然意味着將會有許多類似命名的結構對應到各種版本取決於大小(寒戰)。

當然它不足以保持向後兼容性,但它有幫助。

+0

@Anders:有用的幫助。謝謝。我認爲gtk對僞「階級」歧視也是一樣。 – solotim 2010-04-22 09:31:30

2

最基本的原因是(我不是這裏的C程序員,但我對我的回答相當有信心),那將是一個重大更改

突變意味着這將是一個需要圖書館消費者修改其代碼的變化,這絕不是一件好事。這意味着如果他們想要使用您的圖書館的最新版本,他們將不得不推出他們的程序的新版本,這可能並不總是可行的。

+0

我想要一個用戶域更改的例子。如果該結構的對象完全由庫(malloc/free)維護,並且用戶無法訪問該結構的成員,爲什麼這很危險? – solotim 2010-04-22 09:00:35

+0

在這種情況下,無論您是在編寫代碼的人,都必須與他們交談。我能看到他們不允許的最大原因是它意味着可能花費在新功能或其他更緊急的重構任務上的更多工作,以及可能引入到庫中的新錯誤。 – RCIX 2010-04-22 09:03:29

+3

@solotim:那麼它不是危險的,而且是完全允許的。只有圖書館與世界接口的元素應該保持合理的向後兼容(如果可能,保持不變)。你可以隨心所欲地深入內部深處。請注意,「與世界的接口」是一個廣泛的表達 - 包括函數,但也包括它可能使用的硬件或內存映射區域的結構覆蓋等等。 – 2010-04-22 09:05:23