Is the signedness of char an interface issue?

2019-06-28 04:45发布

Suppose I have a function

void foo(char *)

which, internally, needs to treat its input as a block of NUL-terminated bytes (say, it's a hash function on strings). I could cast the argument to unsigned char* in the function. I could also change the declaration to

void foo(unsigned char *)

Now, given that char, signed char and unsigned char are three different types, would this constitute an interface change, under any reasonable definition of the term "interface" in C?

(This question is intended to settle a discussion raised by another question. I have my opinions, but will not accept an answer until one comes up as a "winner" by the votes of others.)

5条回答
Rolldiameter
2楼-- · 2019-06-28 05:24

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.

查看更多
爷的心禁止访问
3楼-- · 2019-06-28 05:27

Does a char* implicitly convert to an unsigned char*?

  • Yes - you haven't broken your interface
  • No - you've leaked implementation
    details.
查看更多
beautiful°
4楼-- · 2019-06-28 05:28

According to ISO/IEC 9899:TC3,

  • calling a function through an expression of incompatible type is undefined behaviour (6.5.2.2 §9)
  • compatible function types must have compatible parameter types (6.7.5.3 §15)
  • compatible pointer types must point to compatible types (6.7.5.1 §2)
  • char, signed char and unsigned char are different basic types (6.2.5 §14) and thus incompatible (6.2.7 §1), which is also explicitly mentioned in footnote 35 on page 35

So yes, this is clearly a change to the programming interface.

However, as char *, signed char * and unsigned char * will have identical representations and alignment requirements in any sane implementation of the C language, the binary interface will remain unchanged.

查看更多
贪生不怕死
5楼-- · 2019-06-28 05:38

No it isn't. Any change to client code is trivial (especially if it's just to avoid a warning), and in practice in pretty much any C implementation you'll find that you don't even need a re-compile because pointers to char* and unsigned char* will be passed exactly the same way in the calling convention.

查看更多
▲ chillily
6楼-- · 2019-06-28 05:40

Yes it is. Client code which previously compiled will no longer compile (or anyway is likely to generate new warnings), so this is a breaking change.

查看更多
登录 后发表回答