4

私が関数を持っているとしましょう

void foo(char *)

これは、内部的には、入力をNULで終了するバイトのブロックとして扱う必要があります(たとえば、文字列のハッシュ関数です)。関数内で引数をにキャストできunsigned char*ます。宣言を次のように変更することもできます

void foo(unsigned char *)

さて、charsigned charunsigned char3つの異なるタイプであるとすると、Cの「インターフェイス」という用語の合理的な定義の下で、これはインターフェイスの変更を構成しますか?

(この質問は、別の質問によって提起された議論を解決することを目的としています。私は意見を持っていますが、他の人の投票によって「勝者」として現れるまで答えを受け入れません。)

4

5 に答える 5

4

ISO / IEC 9899:TC3によると、

  • 互換性のない型の式を介して関数を呼び出すことは未定義の動作です(6.5.2.2§9)
  • 互換性のある関数型には、互換性のあるパラメーター型が必要です(6.7.5.3§15)
  • 互換性のあるポインタ型は、互換性のある型を指している必要があります(6.7.5.1§2)
  • charsigned 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

私は「C-上記のどれでもない」を選択します。

それはあなたが実際に尋ねた質問に対する直接の答えではありませんが、状況に対する正しい解決策は私にはかなり単純で明白に思えます:あなたは実際に上記のどれも使うべきではありません。

少なくともIMO、そうでない場合は本当に正当な理由があります。関数はvoid *または(できれば)を受け入れる必要がありますvoid const *。あなたが探しているのは基本的に不透明なポインタであり、それがまさにそれをvoid *提供します。ユーザーは実装の内部について何も知る必要はありません。他のポインター型はvoid *暗黙的に変換されるため、既存のコードを壊さない数少ない可能性の1つです。

于 2010-10-23T15:27:06.703 に答える
0

char*は暗黙的にunsignedchar*に変換されますか?

  • はい-あなたはあなたのインターフェースを壊していません

  • いいえ-実装の詳細を漏らしました。
于 2010-10-23T15:08:40.870 に答える
0

いいえ、そうではありません。char*クライアントコードへの変更は簡単です(特に警告を回避するためだけの場合)。実際には、ほとんどすべてのC実装では、ポインタが正確にunsigned char*渡されるため、再コンパイルすら必要ないことがわかります。呼び出し規約でも同じです。

于 2010-10-23T14:59:20.247 に答える