char的签名是否是接口问题?

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

要回复问题请先登录注册