2015-03-12 8 views
3

У меня есть два модуля: a и b.Как обрабатывать круговые зависимости в структурах typedef'd

хиджры:

#ifndef A_H_ 
#define A_H_ 

#include "b.h" 

typedef struct { 
    b_t *b; 
    ... 
} a_t; 

#endif // A_H_ 

b.h:

#ifndef B_H_ 
#define B_H_ 

#include "a.h" 

typedef struct { 
    a_t *a; 
    ... 
} b_t; 

#endif // B_H_ 

Как изменить это так, что он будет собирать? (Я хочу сохранить два отдельных блока компиляции.)


Редактировать: Я забыл сделать элементы структуры указателями.

+2

Сначала я подумал, что члены, где указатели (что еще может быть сомнительным дизайном, но, по крайней мере, возможно с форвард-декларациями и дающим хотя бы одну структуру тегом) ... Что это должно делать? Обе структуры потребуют бесконечного объема памяти, вы не можете сделать 'struct foo {struct foo f; }; по той же причине. – mafso

+1

Последнее примечание: не используйте '_t' в качестве суффикса для типов. Идентификаторы, заканчивающиеся на '_t', зарезервированы POSIX. – fuz

ответ

5

Используйте вперед заявления:

хиджры:

struct b_t; 

typedef struct a_t { 
    struct b_t *b; 
} a_t; 

b.h:

struct a_t; 

typedef struct b_t { 
    struct a_t *a; 
} b_t; 
+0

Спасибо, это было - мне просто пришлось разбить цикл typedefs, используя имя структуры напрямую. – fadedbee

2

[Этот ответ применим только к исходному вопросу, где указатели были , а не, используемые в качестве членов struct].

Вы не можете.

По существу у вас есть

typedef struct { 
    b_t b; 
} a_t; 
typedef struct { 
    a_t a; 
} b_t; 

и не опережающее объявление не может помочь вам. Здесь у вас есть невозможная структура: sizeof будет бесконечным.

+0

Это «вы не можете» относится только к случаю, когда взаимное включение является прямым; это возможно, когда у вас есть указатели. – fuz

+0

В исходном вопросе используются _pointers_. Это не проблема. –

+0

Вопрос был отредактирован: почти все ответы теперь недействительны. – Bathsheba

2

Именно это не представляется возможным. Вы не можете иметь структуру, являющуюся ее собственным членом, даже не транзитивно. Это возможно, если вы используете указатель. Используйте структуру декларации:

typedef struct a_struct *a_t; 

typdef struct { 
    a_t a; 
} *b_t; 

typedef struct a_struct { 
    b_t b; 
} a_t; 
5

[Этот ответ относится только к первоначальному вопросу, где указатели не были использованы в качестве членов STRUCT].

это невозможно. естественно, невозможно иметь такую ​​структуру.

скажем:

struct a { 
    struct b b; 
    int i; 
}; 

struct b { 
    struct a a; 
    int i; 
}; 

что вы ожидаете от sizeof(struct a)? эта структура будет взрываться, ее невозможно скомпилировать.

однако, он может быть собран, если вы их обратиться к указателям:

struct a; 

struct b { 
    struct a *ap; 
}; 

struct a { 
    struct b *bp; 
}; 

этот код действительно компилируется: http://ideone.com/GKdUD9.

+0

В исходном вопросе указатели _were_ используются. Он спрашивал о круговой зависимости от typedef. –

+1

@ColeJohnson в начале этого не было. поэтому все ответы говорят о невозможности. – HuStmpHrrr