4

C でのポインター表現について質問があります。C11 標準のこの段落を正しく理解していれば、次のようになります。

C11 (N1570)、§ 6.2.5.28、タイプ、p。36

同様に、互換性のある型の修飾または非修飾のバージョンへのポインターには、同じ表現およびアライメント要件が必要です。

タイプ とは同じ表現を持っているが、タイプint *と ではないと推測しました。私は正しいですか? int const *int **int const **

もしそうなら、2番目のケースで2つのタイプが同じ表現を持たない理由を知りたいですか? つまり、intint constの同じ表現を持っているので、 とint *int const *問題は何ですか?int **int const **

4

2 に答える 2

1

あなたは正しく、同じ表現を使用する必要がありint *、その要件はありません。int const *int **int const **

同じ表現を必要としない理由は、奇妙なアーキテクチャの C コンパイラに不要な制限を課すことを回避すると同時に、C の仕様を必要以上に理解しにくくしないようにするためです。

たとえば、char*int*のサイズが異なる実装があることに注意してください。これはおそらく、異なる型へのポインターは異なる表現を持つことができるという基本的な仮定につながり、互換性のある型へのポインターと構造体/共用体へのポインターに対して、その基本的な規則の例外が作成されました。

私の知る限り、おそらくDS9Kのコンパイラを除いて、int **とのこの余裕を利用する実装はありません。int const **

于 2013-05-22T10:33:21.027 に答える
1

Bart van Ingen Schenau も述べているように、標準化委員会はポインターの表現にできるだけ制限を加えたくないのだと思います。コンパイラの観点からは、 と を明確に表現できると便利です。これはint *int const *定数をより大きなメモリまたはより小さなメモリに配置でき、その結果、より小さなポインタを使用してより小さなメモリを指すことができるためです。ただし、これは、の%sフォーマット指定子がprintf定数文字列用と非定数文字列用の 2 つのバージョンが必要です。これにより、多くのレガシー コードが壊れてしまいます。標準化委員会には、それをコミュニティに強制する勇気がなかったと思います。そしておそらく当然のことです。int **とに同じ表現を強制するやむを得ない理由がないためint const **、そのままにしてあります。ただし、これらのポインターに異なる表現を使用することは、まれなケースのアプリケーションを除いて、ほとんど役に立ちません。

彼らはまた、 を保存するためだけに同じ表現を持つべきであると決定し かもchar *しれませんが、他のプリミティブ型へのポインターにも同等性を必要とする他のインターフェースがいくつかあるかもしれません。char const *%s

同様に、一部のシステムでは、グローバル メモリ内の何か、スタック上の何か、およびヒープ内の何かに対して異なるポインター表現を使用することが望ましい場合があります。ただし、C では、そのようなポインター (ここでも可変引数を考えることができます) を含むような方法でポインターを使用することが可能であり、したがって、少なくともそれらすべてを表すことができるポインター表現が必要です。

Embedded-C 拡張機能では、C メモリ空間が導入され、プログラマーがデータをすべて表すことができるポインター型を必要とせずに、さまざまなデータ バスからデータを取得できるようになりました。このようなメモリ空間は、定数、ヒープなどの専用メモリを指定するためにも使用できます。したがって、より効率的なポインター表現が可能になります。

私の同僚は、K&R のプロトタイプ、またはそれがなくてもまだ許可されていると述べました。このような場合、コンパイラは、パラメーターの宣言と使用の間の表現の違いを検出できません。これは間違いなく、レガシー ソフトウェアで検出されない多くの問題につながるでしょう。これらの問題は、たとえばvarags でfloattoに対して行われるように、パラメーターの受け渡し (varargs を含む) で共通の表現の使用を要求することによって解決できた可能性がありますが、それは別の表現の意図した効率を損なうことにもなります。double

于 2013-05-26T09:19:51.930 に答える