2016-12-14 5 views
1
int main(void) 
{ 
    struct a 
    { 
     struct b* x; 
    }; 
} 

Iは、struct bを定義しないstruct bへのポインタxを含有するstruct aを定義。私は間違いを予想していた。 -Wallを含めても、私はコンパイラから何も得られませんでした。これについての説明はありますか?構造体に、定義されていない別の構造体へのポインタが含まれているのはなぜですか?

+0

ポインタを作成する方法はわかっています。しかし、 'struct b'を定義せずにそれを逆参照(' x')することはできません。 – e0k

+0

文脈では、 'struct b'は不完全または不透明な型です。実際にはとても便利です。 –

答えて

2

これは単なる標準的な言語機能です。 struct bは不完全なタイプになりました。あなたが不完全な型で行うことはあまりありません。しかし、1つのこと doは、不完全な型へのポインタを宣言しています。

struct bの完全な宣言を後で入力すると、このタイプを完了することができます。その後、通常のstruct型になります。

+0

'*'を削除すると、 'error:field 'x' has incomplete type'というエラーが出ます。それは、不完全な型を含めることは違法ですが、不完全な型へのポインタを含めることは合法であることを意味しますか?これはどのように役立つのでしょうか? –

+0

@W。 Zhu:はい、不完全な型へのポインタを宣言するのは合法ですが、不完全な型のオブジェクトを宣言することは不正です。これは、実装の隠蔽(不透明な型)のような多くの異なる目的に非常に有用です。実際、この機能に頼らずに簡単なリンクリストを宣言することはできません。繰り返しますが、不完全な型は、完全に宣言された時点で、後で完全型になります。 – AnT

2

あなたが持っているものはincomplete typeであり、そのようなタイプのポインタを持つことはまったく問題はありませんが、完了しなければインスタンス化することはできません。

2.7 Incomplete Types

You can define structures, unions, and enumerations without listing their members (or values, in the case of enumerations). Doing so results in an incomplete type. You can’t declare variables of incomplete types, but you can work with pointers to those types.

struct point; 

At some time later in your program you will want to complete the type. You do this by defining it as you usually would:

struct point { 
    int x, y; 
}; 

This technique is commonly used to for linked lists:

struct singly_linked_list { 
    struct singly_linked_list *next; 
    int x; 
    /* other members here perhaps */ 
}; 
struct singly_linked_list *list_head; 
+0

'struct a'は空の構造体へのポインタを含んでいますか? –

+0

@ W.Zhu。前回の回答については、私の更新された回答を参照してください。 – smac89

0

それは、ポインタのサイズを知っているので、コンパイラは、構造体を割り当てることができますが、構造体の定義がない限り、コンパイラがどのようにポインタデリファレンスを知ることができませんので、あなたはxを使用することはできませんので。あなたは前方宣言を使用して、このことの利点を取ることができ

、あなたは未知のstruct型のポインタを宣言し、コンパイル時間と労力を改善するためだけの構造のための可能な大型のヘッダファイルを含む回避することができます。

関連する問題