5

したがって、標準ではポインターのサイズを等しくすることを強制していないことがわかります。( herehere ) (関数ポインタについては話していません)

それが実際にどのように問題になるのか疑問に思っていました。は何でも保持できることがわかっているvoid *ため、ポインターのサイズが異なる場合は、それが最大のサイズになります。それを考えると、avoid **に a を割り当てることchar **はトラブルを意味します。

私の質問は、同じサイズを想定void *して持つことはどれほど危険でしょうか? char *これが正しくないアーキテクチャは実際にありますか?

また、16 ビット dos は私が聞きたいものではありません。;)

4

2 に答える 2

9

void *同じサイズでchar *あることが保証されています。

void **と同じサイズであるとは限りませんchar **(ただし、実装によってはそうなる可能性が非常に高くなります)。

(C99, 6.2.5p27) 「void へのポインタは、文字型へのポインタと同じ表現およびアラインメント要件を持たなければならない [...] 他の型へのポインタは、同じ表現またはアラインメント要件を持つ必要はない.」

于 2012-06-30T16:29:34.010 に答える
3

アラインメント要件に違反しない限り、異なるオブジェクト型のポインターを相互に割り当てることができます。割り当てには (暗黙の) 型変換が含まれるため、afloatを anに割り当てるのと同じくらい (問題はありません) int- ほとんどの場合に機能します。しかし、意味のある変換が不可能な場合は爆破することができます。

char *void *仕様ごとに互換性のあるアラインメント要件があるため、 a を変数に代入することchar **(void **およびその逆) が問題になることはありません。それらは互換性のある表現を持っています。つまり、原則として、char *タイプの式を介してa にアクセスすると (たとえば、実際に a を指しているvoid *a を参照解除することによって)、ほとんどの場合、期待どおりに動作します。もちろん、その逆 ( aを逆参照して a にアクセスする) も当てはまります。void **char *void *char **

たとえば、a を期待し、任意のポインター型を渡すpための変換指定子は、未定義の動作です。ただし、 の場合、実装が C 標準に準拠している限り、特殊なアーキテクチャ (たとえば、異なるポインター表現) でも動作するはずです。printf()void *char *

問題が発生する可能性があるのはエイリアシング分析です。有効な型付け規則により、avoid **と aはエイリアシングchar **できず、プログラマーがその約束を破ると、奇妙なことが起こる可能性があります。効果的な型付け (別名厳密なエイリアシング) のために、C は実際には強く型付けされていることを認識する必要があります。

于 2012-06-30T17:05:31.487 に答える