假设我有一个功能
void foo(char *)
在内部,需要将其输入视为NUL终止字节块(例如,它是字符串上的散列函数)。我可以在函数中将参数强制转换为unsigned char*
。我也可以将声明改为
void foo(unsigned char *)
现在,鉴于char
,signed char
和unsigned char
是three different types,在C中术语“接口”的任何合理定义下,这是否会构成接口更改?
(这个问题的目的是解决另一个问题引起的discussion。我有自己的意见,但在其他人的投票成为“赢家”之前不会接受答案。)
答案 0 :(得分:4)
根据ISO / IEC 9899:TC3,
char
,signed char
和unsigned char
是不同的基本类型(6.2.5§14),因此不兼容(6.2.7§1),脚注35中也明确提到了这一点第35页所以是的,这显然是对编程接口的改变。
但是,由于char *
,signed char *
和unsigned char *
在C语言的任何理智实现中都具有相同的表示和对齐要求,因此二进制接口将保持不变。
答案 1 :(得分:3)
是的。先前编译的客户端代码将不再编译(或者无论如何都可能产生新警告),因此这是一个重大变化。
答案 2 :(得分:2)
我选择“C - 以上都不是。”
虽然这不是你实际问过的问题的直接答案,但对我来说,正确的解决方案似乎相当简单明了:你不应该真正使用上述任何一种。
至少IMO,你有充分的理由不这样做,你的函数应该接受void *
或(最好)void const *
。你正在寻找的东西基本上是一个不透明的指针,这正是void *
所提供的。用户不需要了解有关实现内部的任何信息,并且由于任何其他指针类型将隐式转换为void *
,因此它是少数几种不会破坏任何现有代码的可能性之一。
答案 3 :(得分:0)
不,不是。对客户端代码的任何更改都是微不足道的(特别是如果它只是为了避免警告),并且在实践中几乎任何C实现中都会发现您甚至不需要重新编译,因为指向char*
的指针并且unsigned char*
将在调用约定中以完全相同的方式传递。
答案 4 :(得分:0)
char *是否隐式转换为unsigned char *?