4

假设我有一个功能

void foo(char *)

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

void foo(unsigned char *)

char现在,鉴于signed charunsigned char三种不同的类型,根据 C 中术语“接口”的任何合理定义,这是否会构成接口更改?

(这个问题是为了解决另一个问题引起的讨论。我有我的意见,但不会接受答案,直到一个人通过其他人的投票成为“赢家”。)

4

5 回答 5

4

根据 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 语言实现中都具有相同的表示和对齐要求,二进制接口将保持不变。

于 2010-10-23T19:48:43.013 回答
3

是的。先前编译的客户端代码将不再编译(或者无论如何可能会生成新的警告),因此这是一个重大更改。

于 2010-10-23T14:57:54.963 回答
2

I choose "C -- none of the above."

Although it's not a direct answer to the question you actually asked, the right solution to the situation seems fairly simple and obvious to me: you shouldn't really be using any of the above.

At least IMO, you have a really good reason to do otherwise, your function should accept a void * or (preferably) void const *. What you're looking for is basically an opaque pointer, and that's exactly what void * provides. The user doesn't need to know anything about the internals of your implementation, and since any other pointer type will convert to void * implicitly, it's one of the few possibilities that doesn't break any existing code either.

于 2010-10-23T15:27:06.703 回答
0

不,不是。对客户端代码的任何更改都是微不足道的(特别是如果它只是为了避免警告),实际上在几乎任何 C 实现中你会发现你甚至不需要重新编译,因为指向char*和的指针unsigned char*将被准确传递调用约定中的方式相同。

于 2010-10-23T14:59:20.247 回答
0

char* 是否隐式转换为 unsigned char*?

  • 是的 - 你没有破坏你的界面
  • 不——你泄露了实现
    细节。
于 2010-10-23T15:08:40.870 回答