言語標準によれば、それらは有効であるため、許可する必要があります。
さて、これがどのように機能するかを尋ねると、それは非常に簡単です。
通常、ポインタは単なるメモリアドレスです。また、オブジェクトが整数バイト(それぞれが一意のアドレスを持っている)で表されている場合は、メモリ内の任意のオブジェクトへのポインタを持つことができます。ここでは、構造ビットフィールドへのポインタを設定できないため、「整数」と言っています(少なくとも、バイト境界で始まり、整数のバイト数を占めるものへのポインタを設定することはできません)。 。
つまり、これPtr2
は事前にわかっているサイズのポインタタイプです(CPUのアドレス空間が0〜4 GBの場合、32ビットのアドレスですべてのバイトをアドレス指定できます。32ビットがこのCPUのネイティブポインタサイズになります)。でそのようなポインタstruct Rec1
にスペースを割り当てることができ、struct Rec2
このポインタが何を指しているのかがまだわかっていなくても、問題のコードにあります。不完全な型として定義されています。これが正式な名前ですPtr1
。Ptr2
このような不完全なポインタ型を言語で実装する理由は非常に実用的です。リンクリストまたはツリーを作成する場合、それらの要素またはノードは、リンクされている他の要素またはノードを何らかの方法で指す必要があります。理論的には、最後の要素(またはリーフノード)に対して、次にそれを指す要素に対して、次にその要素を指す要素に対して、というように、個別の要素/ノードタイプを作成できます。ただし、要素またはノードが数個以上ある場合、これは適切にスケーリングされません。あなたがそれらの百万が欲しい場合はどうなりますか?ほぼ同一のタイプを100万個定義することは、せいぜい実用的ではありません。したがって、この言語はこれを回避するためのショートカットを提供します。next
ポインタを単なるポインタとして宣言することもできますvoid*
が、その場合は、ポインタをどこにでもキャストする必要がありますstruct Rect1*
。struct Rect2*
このようなコードの保守とデバッグはエラーが発生しやすくなります。だから、そこで、言語はあなたに手を差し伸べます。