2017-07-12 33 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编译器,“静态内联”功能与宏一样快。) –

相关问题