2017-07-12 30 views
1

據說由於libxml2使用unsigned char作爲存儲器,使字符集之間的編碼/解碼變得方便----強制用戶在代碼中無處不在編寫「BAD_CAST」時,在讀取/創建xml節點名時,內容,文本節點等。爲什麼libxml2在C/C++代碼的每個地方都使用「BAD_CAST」?

有沒有辦法避免在任何地方寫這樣的「BAD_CAST」?設計非常糟糕。

+0

這是不好的設計,他們應該使用'uint8_t'而不是'unsigned char'。 – JeremyP

+0

對於那些擁有'typedef unsigned char byte;'的人來說,C++ 17和'std :: byte'會讓情況變得更糟。你不能'使用byte = std :: byte',因爲'std :: byte'有很多限制。例如,試圖「std :: byte b = ...;'然後'b | = 0x20;'或'b - = 0x10;'編譯失敗。 – jww

+0

@JeremyP libxml2於1999年首次發佈,當時引入'uint8_t'的C99標準甚至未發佈。即使在今天,也有沒有完全支持C99的平臺。此外,C99不保證任何'uint * _t'類型都可用。另外,uint8_t'如何提供幫助?在大多數平臺上,它的typedef是'unsigned char',所以你仍然需要像字符串文字這樣的東西。人們只能爭辯說,libxml2應該使用普通的'char'作爲其公共API,並在內部強制轉換爲無符號類型。 – nwellnhof

回答

3

這種設計決策是不幸的,但根植於另一個不幸的選擇在40年前提出:允許char在默認情況下,這也符合getchar()strcmp()行爲不一致將可能簽署...

您可以使用內聯函數從char *轉換爲unsigned char *,反之亦然含有隱藏施放,使用這些經過時參數:

static inline unsigned char *c2uc(char *s) { return (unsigned char*)s; } 
static inline char *uc2c(unsigned char *s) { return (char*)s; } 

這些包裝更加安全比基本鑄件使用,因爲它們只能是應用於一種類型並轉換爲其對應的unsigned。普通轉換有問題,因爲它們可以應用於任何類型和隱藏類型轉換錯誤。編譯器不需要運行時成本就能擴展功能。

+0

你可能想要在參數和結果上加上'const'限定符。 – JeremyP

+0

@JeremyP:是的,你實際上需要一個單獨的包裝指針的const指針(與C不同的名稱)。 – chqrlie

+1

這可能會提供一個簡短的解釋,說明爲什麼*宏轉換不好(即,沒有對參數進行類型檢查),並且使用「靜態內聯」函數修復了這個問題。 (並且使用當前的C編譯器,「靜態內聯」功能與宏一樣快。) –

相關問題