Структуры внутри Структуры C / C ++ - PullRequest
1 голос
/ 09 мая 2011

Я только недавно перешел от программирования на Java к программированию на C / C ++, так что простите, если это глупый вопрос:

У меня есть файл заголовка, который состоит из структуры, которая включает 2 структуры из другого файла заголовка в другом месте. Это выглядит примерно так:

struct A {
   struct B variable1;
   struct C *variable2;
   ... more variable declarations here.
};

Заголовочные файлы, которые содержат объявления для структуры B и структуры C, не включены в этот конкретный заголовочный файл, но даже если я их включу, это не имеет значения - в обоих сценариях во время компиляции я получаю

error: field 'variable1' has incomplete type

Мне просто интересно, кто-нибудь знает, откуда это может быть? Спасибо!

Ответы [ 5 ]

4 голосов
/ 09 мая 2011

Если вы не включите определение struct B, вы должны получить указанную ошибку, так как размер структуры тогда неизвестен. Тип struct C, на который у вас есть только указатель, может быть предварительно объявлен:

struct C;

Если вы включаете файл с определением struct B, вы не должны получать сообщение об ошибке, поэтому, если вы все равно делаете это, это указывает на какую-то другую ошибку в вашем коде.

1 голос
/ 09 мая 2011

Чтобы объявить экземпляр struct B, определение struct B должно быть complete .Вы заявляете, что

Заголовочные файлы, которые содержат объявления для структуры B и структуры C, не включены в этот конкретный заголовочный файл

На данный момент компилятор незнать, как выглядит struct B, поэтому тип неполный ;таким образом, он отклонит любое объявление, которое пытается создать экземпляр из struct B, такое как объявление для variable1.Вы можете объявить указатель на неполный тип, как вы делаете с variable2, так как все типы структурных указателей имеют одинаковый размер и представление.

Затем вы заявляете

, но даже если я включу их, это не имеет значения

, что настоятельно рекомендует (во всяком случае, мне) круговую зависимостьмежду struct A и struct B, что плохо для Джуджу.struct A не может быть завершено до тех пор, пока struct B не будет завершено, а struct B не может быть завершено до struct A.Изменение variable1 на указатель на struct B должно быть достаточно, чтобы сломать эту зависимость.

Если это так, вы можете пересмотреть свой дизайн.

1 голос
/ 09 мая 2011

Может ли быть порядок, в котором определены структуры? Структуру B необходимо определить и подготовить перед структурой A.

Мой тест был: работает

struct b {
  int y;
};

struct a {
  int x;
  struct b c;
};

та же ошибка, что и у вас:

struct a {
  int x;
  struct b c;
};

struct b {
  int y;
};
0 голосов
/ 09 мая 2011

struct A определена здесь, и она должна иметь известный размер. Компилятор должен знать, каков размер struct B , чтобы вычислить размер struct A , поэтому, если struct B еще не определена, вы не будете уметь использовать его в struct A .

У вас нет такой проблемы с struct C *, поскольку структура A сохраняет только указатель на struct C , а размер указателя известен компилятору. Но вам нужно использовать для этого предварительное объявление, если оно не определено до struct A :

struct B {
   int b;
}
struct C;
struct A {
   struct B variable1;  // valid
   struct C *variable2; // valid
   struct D variable3;  // invalid
   struct D* variable4; // invalid
};

struct C {
    int c;
}

struct D {
    int d;
}
0 голосов
/ 09 мая 2011

Попробуйте переслать декларацию:

struct B;
struct C;  
struct A {
   struct B variable1;
   struct C *variable2;
   ... more variable declarations here.
};
...