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

时间:2010-10-23 14:53:56

标签: c interface unsigned-char signedness

假设我有一个功能

void foo(char *)

在内部,需要将其输入视为NUL终止字节块(例如,它是字符串上的散列函数)。我可以在函数中将参数强制转换为unsigned char*。我也可以将声明改为

void foo(unsigned char *)

现在,鉴于charsigned charunsigned charthree different types,在C中术语“接口”的任何合理定义下,这是否会构成接口更改?

(这个问题的目的是解决另一个问题引起的discussion。我有自己的意见,但在其他人的投票成为“赢家”之前不会接受答案。)

5 个答案:

答案 0 :(得分:4)

根据ISO / IEC 9899:TC3,

  • 通过不兼容类型的表达式调用函数是未定义的行为(6.5.2.2§9)
  • 兼容的函数类型必须具有兼容的参数类型(6.7.5.3§15)
  • 兼容指针类型必须指向兼容类型(6.7.5.1§2)
  • charsigned charunsigned 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 *?

  • 是 - 您没有破坏您的界面
  • 不 - 你已经泄露了执行情况 的信息。